2 * Copyright (C) 2006-2007 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.internal.os;
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.ActivityManager;
22 import android.bluetooth.BluetoothActivityEnergyInfo;
23 import android.bluetooth.UidTraffic;
24 import android.content.ContentResolver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.database.ContentObserver;
28 import android.net.ConnectivityManager;
29 import android.net.NetworkStats;
30 import android.net.Uri;
31 import android.net.wifi.WifiActivityEnergyInfo;
32 import android.net.wifi.WifiManager;
33 import android.os.BatteryManager;
34 import android.os.BatteryStats;
35 import android.os.Build;
36 import android.os.connectivity.CellularBatteryStats;
37 import android.os.connectivity.WifiBatteryStats;
38 import android.os.connectivity.GpsBatteryStats;
39 import android.os.FileUtils;
40 import android.os.Handler;
41 import android.os.IBatteryPropertiesRegistrar;
42 import android.os.Looper;
43 import android.os.Message;
44 import android.os.OsProtoEnums;
45 import android.os.Parcel;
46 import android.os.ParcelFormatException;
47 import android.os.Parcelable;
48 import android.os.PowerManager;
49 import android.os.Process;
50 import android.os.RemoteException;
51 import android.os.ServiceManager;
52 import android.os.SystemClock;
53 import android.os.UserHandle;
54 import android.os.WorkSource;
55 import android.os.WorkSource.WorkChain;
56 import android.provider.Settings;
57 import android.telephony.DataConnectionRealTimeInfo;
58 import android.telephony.ModemActivityInfo;
59 import android.telephony.ServiceState;
60 import android.telephony.SignalStrength;
61 import android.telephony.TelephonyManager;
62 import android.text.TextUtils;
63 import android.util.ArrayMap;
64 import android.util.IntArray;
65 import android.util.KeyValueListParser;
66 import android.util.Log;
67 import android.util.LogWriter;
68 import android.util.LongSparseArray;
69 import android.util.LongSparseLongArray;
70 import android.util.MutableInt;
71 import android.util.Pools;
72 import android.util.PrintWriterPrinter;
73 import android.util.Printer;
74 import android.util.Slog;
75 import android.util.SparseArray;
76 import android.util.SparseIntArray;
77 import android.util.SparseLongArray;
78 import android.util.StatsLog;
79 import android.util.TimeUtils;
80 import android.util.Xml;
81 import android.view.Display;
83 import com.android.internal.annotations.GuardedBy;
84 import com.android.internal.annotations.VisibleForTesting;
85 import com.android.internal.location.gnssmetrics.GnssMetrics;
86 import com.android.internal.net.NetworkStatsFactory;
87 import com.android.internal.util.ArrayUtils;
88 import com.android.internal.util.FastPrintWriter;
89 import com.android.internal.util.FastXmlSerializer;
90 import com.android.internal.util.JournaledFile;
91 import com.android.internal.util.XmlUtils;
93 import java.util.List;
94 import libcore.util.EmptyArray;
95 import org.xmlpull.v1.XmlPullParser;
96 import org.xmlpull.v1.XmlPullParserException;
97 import org.xmlpull.v1.XmlSerializer;
99 import java.io.ByteArrayOutputStream;
101 import java.io.FileInputStream;
102 import java.io.FileNotFoundException;
103 import java.io.FileOutputStream;
104 import java.io.IOException;
105 import java.io.PrintWriter;
106 import java.nio.charset.StandardCharsets;
107 import java.util.ArrayList;
108 import java.util.Arrays;
109 import java.util.Calendar;
110 import java.util.HashMap;
111 import java.util.Iterator;
112 import java.util.Map;
113 import java.util.concurrent.Future;
114 import java.util.concurrent.atomic.AtomicInteger;
115 import java.util.concurrent.locks.ReentrantLock;
118 * All information we are collecting about things that can happen that impact
119 * battery life. All times are represented in microseconds except where indicated
122 public class BatteryStatsImpl extends BatteryStats {
123 private static final String TAG = "BatteryStatsImpl";
124 private static final boolean DEBUG = false;
125 public static final boolean DEBUG_ENERGY = false;
126 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY;
127 private static final boolean DEBUG_MEMORY = false;
128 private static final boolean DEBUG_HISTORY = false;
129 private static final boolean USE_OLD_HISTORY = false; // for debugging.
131 // TODO: remove "tcp" from network methods, since we measure total stats.
133 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
134 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
136 // Current on-disk Parcel version
137 private static final int VERSION = 175 + (USE_OLD_HISTORY ? 1000 : 0);
139 // Maximum number of items we will record in the history.
140 private static final int MAX_HISTORY_ITEMS;
142 // No, really, THIS is the maximum number of items we will record in the history.
143 private static final int MAX_MAX_HISTORY_ITEMS;
145 // The maximum number of names wakelocks we will keep track of
146 // per uid; once the limit is reached, we batch the remaining wakelocks
147 // in to one common name.
148 private static final int MAX_WAKELOCKS_PER_UID;
150 static final int MAX_HISTORY_BUFFER; // 256KB
151 static final int MAX_MAX_HISTORY_BUFFER; // 320KB
154 if (ActivityManager.isLowRamDeviceStatic()) {
155 MAX_HISTORY_ITEMS = 800;
156 MAX_MAX_HISTORY_ITEMS = 1200;
157 MAX_WAKELOCKS_PER_UID = 40;
158 MAX_HISTORY_BUFFER = 96*1024; // 96KB
159 MAX_MAX_HISTORY_BUFFER = 128*1024; // 128KB
161 MAX_HISTORY_ITEMS = 4000;
162 MAX_MAX_HISTORY_ITEMS = 6000;
163 MAX_WAKELOCKS_PER_UID = 200;
164 MAX_HISTORY_BUFFER = 512*1024; // 512KB
165 MAX_MAX_HISTORY_BUFFER = 640*1024; // 640KB
169 // Number of transmit power states the Wifi controller can be in.
170 private static final int NUM_WIFI_TX_LEVELS = 1;
172 // Number of transmit power states the Bluetooth controller can be in.
173 private static final int NUM_BT_TX_LEVELS = 1;
176 * Holding a wakelock costs more than just using the cpu.
177 * Currently, we assign only half the cpu time to an app that is running but
178 * not holding a wakelock. The apps holding wakelocks get the rest of the blame.
179 * If no app is holding a wakelock, then the distribution is normal.
182 public static final int WAKE_LOCK_WEIGHT = 50;
184 protected Clocks mClocks;
186 private final JournaledFile mFile;
187 public final AtomicFile mCheckinFile;
188 public final AtomicFile mDailyFile;
190 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1;
191 static final int MSG_REPORT_POWER_CHANGE = 2;
192 static final int MSG_REPORT_CHARGING = 3;
193 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
195 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
196 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
199 protected KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
201 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
203 protected KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader =
204 new KernelUidCpuFreqTimeReader();
206 protected KernelUidCpuActiveTimeReader mKernelUidCpuActiveTimeReader =
207 new KernelUidCpuActiveTimeReader();
209 protected KernelUidCpuClusterTimeReader mKernelUidCpuClusterTimeReader =
210 new KernelUidCpuClusterTimeReader();
212 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader;
214 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats
215 = new KernelMemoryBandwidthStats();
216 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>();
217 public LongSparseArray<SamplingTimer> getKernelMemoryStats() {
218 return mKernelMemoryStats;
222 public boolean mPerProcStateCpuTimesAvailable = true;
225 * Uids for which per-procstate cpu times need to be updated.
227 * Contains uid -> procState mappings.
231 protected final SparseIntArray mPendingUids = new SparseIntArray();
234 private long mNumCpuTimeReads;
236 private long mNumBatchedCpuTimeReads;
238 private long mCpuTimeReadsTrackingStartTime = SystemClock.uptimeMillis();
240 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */
241 private final RpmStats mTmpRpmStats = new RpmStats();
242 /** The soonest the RPM stats can be updated after it was last updated. */
243 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000;
244 /** Last time that RPM stats were updated by updateRpmStatsLocked. */
245 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS;
247 public interface BatteryCallback {
248 public void batteryNeedsCpuUpdate();
249 public void batteryPowerChanged(boolean onBattery);
250 public void batterySendBroadcast(Intent intent);
253 public interface PlatformIdleStateCallback {
254 public void fillLowPowerStats(RpmStats rpmStats);
255 public String getPlatformLowPowerStats();
256 public String getSubsystemLowPowerStats();
259 public static abstract class UserInfoProvider {
260 private int[] userIds;
261 protected abstract @Nullable int[] getUserIds();
263 public final void refreshUserIds() {
264 userIds = getUserIds();
267 public boolean exists(int userId) {
268 return userIds != null ? ArrayUtils.contains(userIds, userId) : true;
272 private final PlatformIdleStateCallback mPlatformIdleStateCallback;
274 final class MyHandler extends Handler {
275 public MyHandler(Looper looper) {
276 super(looper, null, true);
280 public void handleMessage(Message msg) {
281 BatteryCallback cb = mCallback;
283 case MSG_REPORT_CPU_UPDATE_NEEDED:
285 cb.batteryNeedsCpuUpdate();
288 case MSG_REPORT_POWER_CHANGE:
290 cb.batteryPowerChanged(msg.arg1 != 0);
293 case MSG_REPORT_CHARGING:
296 synchronized (BatteryStatsImpl.this) {
297 action = mCharging ? BatteryManager.ACTION_CHARGING
298 : BatteryManager.ACTION_DISCHARGING;
300 Intent intent = new Intent(action);
301 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
302 cb.batterySendBroadcast(intent);
309 public void postBatteryNeedsCpuUpdateMsg() {
310 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED);
314 * Update per-freq cpu times for all the uids in {@link #mPendingUids}.
316 public void updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff) {
317 final SparseIntArray uidStates;
318 synchronized (BatteryStatsImpl.this) {
319 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) {
322 if(!initKernelSingleUidTimeReaderLocked()) {
325 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to
326 // compute deltas since it might result in mis-attributing cpu times to wrong states.
327 if (mKernelSingleUidTimeReader.hasStaleData()) {
328 mPendingUids.clear();
332 if (mPendingUids.size() == 0) {
335 uidStates = mPendingUids.clone();
336 mPendingUids.clear();
338 for (int i = uidStates.size() - 1; i >= 0; --i) {
339 final int uid = uidStates.keyAt(i);
340 final int procState = uidStates.valueAt(i);
341 final int[] isolatedUids;
343 synchronized (BatteryStatsImpl.this) {
344 // It's possible that uid no longer exists and any internal references have
345 // already been deleted, so using {@link #getAvailableUidStatsLocked} to avoid
346 // creating an UidStats object if it doesn't already exist.
347 u = getAvailableUidStatsLocked(uid);
351 if (u.mChildUids == null) {
354 isolatedUids = u.mChildUids.toArray();
355 for (int j = isolatedUids.length - 1; j >= 0; --j) {
356 isolatedUids[j] = u.mChildUids.get(j);
360 long[] cpuTimesMs = mKernelSingleUidTimeReader.readDeltaMs(uid);
361 if (isolatedUids != null) {
362 for (int j = isolatedUids.length - 1; j >= 0; --j) {
363 cpuTimesMs = addCpuTimes(cpuTimesMs,
364 mKernelSingleUidTimeReader.readDeltaMs(isolatedUids[j]));
367 if (onBattery && cpuTimesMs != null) {
368 synchronized (BatteryStatsImpl.this) {
369 u.addProcStateTimesMs(procState, cpuTimesMs, onBattery);
370 u.addProcStateScreenOffTimesMs(procState, cpuTimesMs, onBatteryScreenOff);
376 public void copyFromAllUidsCpuTimes() {
377 synchronized (BatteryStatsImpl.this) {
378 copyFromAllUidsCpuTimes(
379 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning());
384 * When the battery/screen state changes, we don't attribute the cpu times to any process
385 * but we still need to snapshots of all uids to get correct deltas later on. Since we
386 * already read this data for updating per-freq cpu times, we can use the same data for
387 * per-procstate cpu times.
389 public void copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff) {
390 synchronized (BatteryStatsImpl.this) {
391 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) {
394 if(!initKernelSingleUidTimeReaderLocked()) {
398 final SparseArray<long[]> allUidCpuFreqTimesMs =
399 mKernelUidCpuFreqTimeReader.getAllUidCpuFreqTimeMs();
400 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to
401 // compute deltas since it might result in mis-attributing cpu times to wrong states.
402 if (mKernelSingleUidTimeReader.hasStaleData()) {
403 mKernelSingleUidTimeReader.setAllUidsCpuTimesMs(allUidCpuFreqTimesMs);
404 mKernelSingleUidTimeReader.markDataAsStale(false);
405 mPendingUids.clear();
408 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) {
409 final int uid = allUidCpuFreqTimesMs.keyAt(i);
410 final Uid u = getAvailableUidStatsLocked(mapUid(uid));
414 final long[] cpuTimesMs = allUidCpuFreqTimesMs.valueAt(i);
415 if (cpuTimesMs == null) {
418 final long[] deltaTimesMs = mKernelSingleUidTimeReader.computeDelta(
419 uid, cpuTimesMs.clone());
420 if (onBattery && deltaTimesMs != null) {
422 final int idx = mPendingUids.indexOfKey(uid);
424 procState = mPendingUids.valueAt(idx);
425 mPendingUids.removeAt(idx);
427 procState = u.mProcessState;
429 if (procState >= 0 && procState < Uid.NUM_PROCESS_STATE) {
430 u.addProcStateTimesMs(procState, deltaTimesMs, onBattery);
431 u.addProcStateScreenOffTimesMs(procState, deltaTimesMs, onBatteryScreenOff);
439 public long[] addCpuTimes(long[] timesA, long[] timesB) {
440 if (timesA != null && timesB != null) {
441 for (int i = timesA.length - 1; i >= 0; --i) {
442 timesA[i] += timesB[i];
446 return timesA == null ? (timesB == null ? null : timesB) : timesA;
450 private boolean initKernelSingleUidTimeReaderLocked() {
451 if (mKernelSingleUidTimeReader == null) {
452 if (mPowerProfile == null) {
455 if (mCpuFreqs == null) {
456 mCpuFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile);
458 if (mCpuFreqs != null) {
459 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader(mCpuFreqs.length);
461 mPerProcStateCpuTimesAvailable = mKernelUidCpuFreqTimeReader.allUidTimesAvailable();
465 mPerProcStateCpuTimesAvailable = mKernelUidCpuFreqTimeReader.allUidTimesAvailable()
466 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable();
470 public interface Clocks {
471 public long elapsedRealtime();
472 public long uptimeMillis();
475 public static class SystemClocks implements Clocks {
476 public long elapsedRealtime() {
477 return SystemClock.elapsedRealtime();
480 public long uptimeMillis() {
481 return SystemClock.uptimeMillis();
485 public interface ExternalStatsSync {
486 int UPDATE_CPU = 0x01;
487 int UPDATE_WIFI = 0x02;
488 int UPDATE_RADIO = 0x04;
489 int UPDATE_BT = 0x08;
490 int UPDATE_RPM = 0x10; // 16
491 int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM;
493 Future<?> scheduleSync(String reason, int flags);
494 Future<?> scheduleCpuSyncDueToRemovedUid(int uid);
495 Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff,
497 Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff);
498 Future<?> scheduleCpuSyncDueToSettingChange();
499 Future<?> scheduleCpuSyncDueToScreenStateChange(boolean onBattery,
500 boolean onBatteryScreenOff);
501 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis);
502 void cancelCpuSyncDueToWakelockChange();
505 public Handler mHandler;
506 private ExternalStatsSync mExternalSync = null;
508 protected UserInfoProvider mUserInfoProvider = null;
510 private BatteryCallback mCallback;
513 * Mapping isolated uids to the actual owning app uid.
515 final SparseIntArray mIsolatedUids = new SparseIntArray();
518 * The statistics we have collected organized by uids.
520 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>();
522 // A set of pools of currently active timers. When a timer is queried, we will divide the
523 // elapsed time by the number of active timers to arrive at that timer's share of the time.
524 // In order to do this, we must refresh each timer whenever the number of active timers
527 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
528 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
529 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
530 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>();
531 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
532 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
533 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
534 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
535 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
536 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
537 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
538 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
539 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>();
540 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>();
541 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>();
543 // Last partial timers we use for distributing CPU usage.
545 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
547 // These are the objects that will want to do something when the device
548 // is unplugged from power.
549 protected final TimeBase mOnBatteryTimeBase = new TimeBase();
551 // These are the objects that will want to do something when the device
552 // is unplugged from power *and* the screen is off or doze.
553 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
555 // Set to true when we want to distribute CPU across wakelocks for the next
556 // CPU update, even if we aren't currently running wake locks.
557 boolean mDistributeWakelockCpu;
559 boolean mShuttingDown;
561 final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
563 long mHistoryBaseTime;
564 protected boolean mHaveBatteryLevel = false;
565 protected boolean mRecordingHistory = false;
566 int mNumHistoryItems;
568 final Parcel mHistoryBuffer = Parcel.obtain();
569 final HistoryItem mHistoryLastWritten = new HistoryItem();
570 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
571 final HistoryItem mHistoryReadTmp = new HistoryItem();
572 final HistoryItem mHistoryAddTmp = new HistoryItem();
573 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
574 String[] mReadHistoryStrings;
575 int[] mReadHistoryUids;
576 int mReadHistoryChars;
577 int mNextHistoryTagIdx = 0;
578 int mNumHistoryTagChars = 0;
579 int mHistoryBufferLastPos = -1;
580 boolean mHistoryOverflow = false;
581 int mActiveHistoryStates = 0xffffffff;
582 int mActiveHistoryStates2 = 0xffffffff;
583 long mLastHistoryElapsedRealtime = 0;
584 long mTrackRunningHistoryElapsedRealtime = 0;
585 long mTrackRunningHistoryUptime = 0;
587 final HistoryItem mHistoryCur = new HistoryItem();
589 HistoryItem mHistory;
590 HistoryItem mHistoryEnd;
591 HistoryItem mHistoryLastEnd;
592 HistoryItem mHistoryCache;
594 // Used by computeHistoryStepDetails
595 HistoryStepDetails mLastHistoryStepDetails = null;
596 byte mLastHistoryStepLevel = 0;
597 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
598 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails();
599 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
602 * Total time (in milliseconds) spent executing in user code.
604 long mLastStepCpuUserTime;
605 long mCurStepCpuUserTime;
607 * Total time (in milliseconds) spent executing in kernel code.
609 long mLastStepCpuSystemTime;
610 long mCurStepCpuSystemTime;
612 * Times from /proc/stat (but measured in milliseconds).
614 long mLastStepStatUserTime;
615 long mLastStepStatSystemTime;
616 long mLastStepStatIOWaitTime;
617 long mLastStepStatIrqTime;
618 long mLastStepStatSoftIrqTime;
619 long mLastStepStatIdleTime;
620 long mCurStepStatUserTime;
621 long mCurStepStatSystemTime;
622 long mCurStepStatIOWaitTime;
623 long mCurStepStatIrqTime;
624 long mCurStepStatSoftIrqTime;
625 long mCurStepStatIdleTime;
627 private HistoryItem mHistoryIterator;
628 private boolean mReadOverflow;
629 private boolean mIteratingHistory;
633 long mStartClockTime;
634 String mStartPlatformVersion;
635 String mEndPlatformVersion;
642 int mWakeLockNesting;
643 boolean mWakeLockImportant;
644 public boolean mRecordAllHistory;
645 boolean mNoAutoReset;
647 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
648 protected int mScreenState = Display.STATE_UNKNOWN;
649 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
650 protected StopwatchTimer mScreenOnTimer;
651 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
652 protected StopwatchTimer mScreenDozeTimer;
654 int mScreenBrightnessBin = -1;
655 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
657 boolean mPretendScreenOff;
659 boolean mInteractive;
660 StopwatchTimer mInteractiveTimer;
662 boolean mPowerSaveModeEnabled;
663 StopwatchTimer mPowerSaveModeEnabledTimer;
665 boolean mDeviceIdling;
666 StopwatchTimer mDeviceIdlingTimer;
668 boolean mDeviceLightIdling;
669 StopwatchTimer mDeviceLightIdlingTimer;
672 long mLastIdleTimeStart;
673 long mLongestLightIdleTime;
674 long mLongestFullIdleTime;
675 StopwatchTimer mDeviceIdleModeLightTimer;
676 StopwatchTimer mDeviceIdleModeFullTimer;
679 StopwatchTimer mPhoneOnTimer;
682 StopwatchTimer mAudioOnTimer;
685 StopwatchTimer mVideoOnTimer;
687 int mFlashlightOnNesting;
688 StopwatchTimer mFlashlightOnTimer;
690 int mCameraOnNesting;
691 StopwatchTimer mCameraOnTimer;
693 int mGpsSignalQualityBin = -1;
694 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
695 protected final StopwatchTimer[] mGpsSignalQualityTimer =
696 new StopwatchTimer[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS];
698 int mPhoneSignalStrengthBin = -1;
699 int mPhoneSignalStrengthBinRaw = -1;
700 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
701 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
703 StopwatchTimer mPhoneSignalScanningTimer;
705 int mPhoneDataConnectionType = -1;
706 final StopwatchTimer[] mPhoneDataConnectionsTimer =
707 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
709 final LongSamplingCounter[] mNetworkByteActivityCounters =
710 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
711 final LongSamplingCounter[] mNetworkPacketActivityCounters =
712 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
715 * The WiFi Overall wakelock timer
716 * This timer tracks the actual aggregate time for which MC wakelocks are enabled
717 * since addition of per UID timers would not result in an accurate value due to overlapp of
718 * per uid wakelock timers
720 StopwatchTimer mWifiMulticastWakelockTimer;
723 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device.
725 ControllerActivityCounterImpl mWifiActivity;
728 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device.
730 ControllerActivityCounterImpl mBluetoothActivity;
733 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device.
735 ControllerActivityCounterImpl mModemActivity;
738 * Whether the device supports WiFi controller energy reporting. This is set to true on
739 * the first WiFi energy report. See {@link #mWifiActivity}.
741 boolean mHasWifiReporting = false;
744 * Whether the device supports Bluetooth controller energy reporting. This is set to true on
745 * the first Bluetooth energy report. See {@link #mBluetoothActivity}.
747 boolean mHasBluetoothReporting = false;
750 * Whether the device supports Modem controller energy reporting. This is set to true on
751 * the first Modem energy report. See {@link #mModemActivity}.
753 boolean mHasModemReporting = false;
756 StopwatchTimer mWifiOnTimer;
758 boolean mGlobalWifiRunning;
759 StopwatchTimer mGlobalWifiRunningTimer;
762 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
764 int mWifiSupplState = -1;
765 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES];
767 int mWifiSignalStrengthBin = -1;
768 final StopwatchTimer[] mWifiSignalStrengthsTimer =
769 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS];
771 StopwatchTimer mWifiActiveTimer;
773 int mBluetoothScanNesting;
774 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
775 protected StopwatchTimer mBluetoothScanTimer;
777 boolean mIsCellularTxPowerHigh = false;
779 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
780 long mMobileRadioActiveStartTime;
781 StopwatchTimer mMobileRadioActiveTimer;
782 StopwatchTimer mMobileRadioActivePerAppTimer;
783 LongSamplingCounter mMobileRadioActiveAdjustedTime;
784 LongSamplingCounter mMobileRadioActiveUnknownTime;
785 LongSamplingCounter mMobileRadioActiveUnknownCount;
787 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
790 * These provide time bases that discount the time the device is plugged
795 protected boolean mOnBatteryInternal;
798 * External reporting of whether the device is actually charging.
800 boolean mCharging = true;
801 int mLastChargingStateLevel;
804 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
806 int mDischargeStartLevel;
807 int mDischargeUnplugLevel;
808 int mDischargePlugLevel;
809 int mDischargeCurrentLevel;
810 int mCurrentBatteryLevel;
811 int mLowDischargeAmountSinceCharge;
812 int mHighDischargeAmountSinceCharge;
813 int mDischargeScreenOnUnplugLevel;
814 int mDischargeScreenOffUnplugLevel;
815 int mDischargeScreenDozeUnplugLevel;
816 int mDischargeAmountScreenOn;
817 int mDischargeAmountScreenOnSinceCharge;
818 int mDischargeAmountScreenOff;
819 int mDischargeAmountScreenOffSinceCharge;
820 int mDischargeAmountScreenDoze;
821 int mDischargeAmountScreenDozeSinceCharge;
823 private LongSamplingCounter mDischargeScreenOffCounter;
824 private LongSamplingCounter mDischargeScreenDozeCounter;
825 private LongSamplingCounter mDischargeCounter;
826 private LongSamplingCounter mDischargeLightDozeCounter;
827 private LongSamplingCounter mDischargeDeepDozeCounter;
829 static final int MAX_LEVEL_STEPS = 200;
831 int mInitStepMode = 0;
832 int mCurStepMode = 0;
833 int mModStepMode = 0;
835 int mLastDischargeStepLevel;
836 int mMinDischargeStepLevel;
837 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
838 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
839 ArrayList<PackageChange> mDailyPackageChanges;
841 int mLastChargeStepLevel;
842 int mMaxChargeStepLevel;
843 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
844 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
846 static final int MAX_DAILY_ITEMS = 10;
848 long mDailyStartTime = 0;
849 long mNextMinDailyDeadline = 0;
850 long mNextMaxDailyDeadline = 0;
852 final ArrayList<DailyItem> mDailyItems = new ArrayList<>();
854 long mLastWriteTime = 0; // Milliseconds
856 private int mPhoneServiceState = -1;
857 private int mPhoneServiceStateRaw = -1;
858 private int mPhoneSimStateRaw = -1;
860 private int mNumConnectivityChange;
861 private int mLoadedNumConnectivityChange;
862 private int mUnpluggedNumConnectivityChange;
864 private int mEstimatedBatteryCapacity = -1;
866 private int mMinLearnedBatteryCapacity = -1;
867 private int mMaxLearnedBatteryCapacity = -1;
869 private long[] mCpuFreqs;
872 protected PowerProfile mPowerProfile;
875 private final Constants mConstants;
878 * Holds a SamplingTimer associated with each Resource Power Manager state and voter,
879 * recording their times when on-battery (regardless of screen state).
881 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>();
882 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */
883 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>();
886 public Map<String, ? extends Timer> getRpmStats() {
890 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED.
892 public Map<String, ? extends Timer> getScreenOffRpmStats() {
893 return mScreenOffRpmStats;
897 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
899 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>();
901 public Map<String, ? extends Timer> getKernelWakelockStats() {
902 return mKernelWakelockStats;
905 String mLastWakeupReason = null;
906 long mLastWakeupUptimeMs = 0;
907 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>();
909 public Map<String, ? extends Timer> getWakeupReasonStats() {
910 return mWakeupReasonStats;
914 public long getUahDischarge(int which) {
915 return mDischargeCounter.getCountLocked(which);
919 public long getUahDischargeScreenOff(int which) {
920 return mDischargeScreenOffCounter.getCountLocked(which);
924 public long getUahDischargeScreenDoze(int which) {
925 return mDischargeScreenDozeCounter.getCountLocked(which);
929 public long getUahDischargeLightDoze(int which) {
930 return mDischargeLightDozeCounter.getCountLocked(which);
934 public long getUahDischargeDeepDoze(int which) {
935 return mDischargeDeepDozeCounter.getCountLocked(which);
939 public int getEstimatedBatteryCapacity() {
940 return mEstimatedBatteryCapacity;
944 public int getMinLearnedBatteryCapacity() {
945 return mMinLearnedBatteryCapacity;
949 public int getMaxLearnedBatteryCapacity() {
950 return mMaxLearnedBatteryCapacity;
953 public BatteryStatsImpl() {
954 this(new SystemClocks());
957 public BatteryStatsImpl(Clocks clocks) {
963 mPlatformIdleStateCallback = null;
964 mUserInfoProvider = null;
965 mConstants = new Constants(mHandler);
966 clearHistoryLocked();
969 private void init(Clocks clocks) {
973 public interface TimeBaseObs {
974 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
975 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
978 // methods are protected not private to be VisibleForTesting
979 public static class TimeBase {
980 protected final ArrayList<TimeBaseObs> mObservers = new ArrayList<>();
982 protected long mUptime;
983 protected long mRealtime;
985 protected boolean mRunning;
987 protected long mPastUptime;
988 protected long mUptimeStart;
989 protected long mPastRealtime;
990 protected long mRealtimeStart;
991 protected long mUnpluggedUptime;
992 protected long mUnpluggedRealtime;
994 public void dump(PrintWriter pw, String prefix) {
995 StringBuilder sb = new StringBuilder(128);
996 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
999 sb.append("mUptime=");
1000 formatTimeMs(sb, mUptime / 1000);
1001 pw.println(sb.toString());
1004 sb.append("mRealtime=");
1005 formatTimeMs(sb, mRealtime / 1000);
1006 pw.println(sb.toString());
1009 sb.append("mPastUptime=");
1010 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
1011 formatTimeMs(sb, mUptimeStart / 1000);
1012 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
1013 pw.println(sb.toString());
1016 sb.append("mPastRealtime=");
1017 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
1018 formatTimeMs(sb, mRealtimeStart / 1000);
1019 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
1020 pw.println(sb.toString());
1023 public void add(TimeBaseObs observer) {
1024 mObservers.add(observer);
1027 public void remove(TimeBaseObs observer) {
1028 if (!mObservers.remove(observer)) {
1029 Slog.wtf(TAG, "Removed unknown observer: " + observer);
1033 public boolean hasObserver(TimeBaseObs observer) {
1034 return mObservers.contains(observer);
1037 public void init(long uptime, long realtime) {
1042 mUptimeStart = uptime;
1043 mRealtimeStart = realtime;
1044 mUnpluggedUptime = getUptime(mUptimeStart);
1045 mUnpluggedRealtime = getRealtime(mRealtimeStart);
1048 public void reset(long uptime, long realtime) {
1053 mUptimeStart = uptime;
1054 mRealtimeStart = realtime;
1055 // TODO: Since mUptimeStart was just reset and we are running, getUptime will
1056 // just return mPastUptime. Also, are we sure we don't want to reset that?
1057 mUnpluggedUptime = getUptime(uptime);
1059 mUnpluggedRealtime = getRealtime(realtime);
1063 public long computeUptime(long curTime, int which) {
1065 case STATS_SINCE_CHARGED:
1066 return mUptime + getUptime(curTime);
1068 return getUptime(curTime);
1069 case STATS_SINCE_UNPLUGGED:
1070 return getUptime(curTime) - mUnpluggedUptime;
1075 public long computeRealtime(long curTime, int which) {
1077 case STATS_SINCE_CHARGED:
1078 return mRealtime + getRealtime(curTime);
1080 return getRealtime(curTime);
1081 case STATS_SINCE_UNPLUGGED:
1082 return getRealtime(curTime) - mUnpluggedRealtime;
1087 public long getUptime(long curTime) {
1088 long time = mPastUptime;
1090 time += curTime - mUptimeStart;
1095 public long getRealtime(long curTime) {
1096 long time = mPastRealtime;
1098 time += curTime - mRealtimeStart;
1103 public long getUptimeStart() {
1104 return mUptimeStart;
1107 public long getRealtimeStart() {
1108 return mRealtimeStart;
1111 public boolean isRunning() {
1115 public boolean setRunning(boolean running, long uptime, long realtime) {
1116 if (mRunning != running) {
1119 mUptimeStart = uptime;
1120 mRealtimeStart = realtime;
1121 long batteryUptime = mUnpluggedUptime = getUptime(uptime);
1122 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
1124 for (int i = mObservers.size() - 1; i >= 0; i--) {
1125 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
1128 mPastUptime += uptime - mUptimeStart;
1129 mPastRealtime += realtime - mRealtimeStart;
1131 long batteryUptime = getUptime(uptime);
1132 long batteryRealtime = getRealtime(realtime);
1134 for (int i = mObservers.size() - 1; i >= 0; i--) {
1135 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
1143 public void readSummaryFromParcel(Parcel in) {
1144 mUptime = in.readLong();
1145 mRealtime = in.readLong();
1148 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
1149 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
1150 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
1153 public void readFromParcel(Parcel in) {
1155 mUptime = in.readLong();
1156 mPastUptime = in.readLong();
1157 mUptimeStart = in.readLong();
1158 mRealtime = in.readLong();
1159 mPastRealtime = in.readLong();
1160 mRealtimeStart = in.readLong();
1161 mUnpluggedUptime = in.readLong();
1162 mUnpluggedRealtime = in.readLong();
1165 public void writeToParcel(Parcel out, long uptime, long realtime) {
1166 final long runningUptime = getUptime(uptime);
1167 final long runningRealtime = getRealtime(realtime);
1168 out.writeLong(mUptime);
1169 out.writeLong(runningUptime);
1170 out.writeLong(mUptimeStart);
1171 out.writeLong(mRealtime);
1172 out.writeLong(runningRealtime);
1173 out.writeLong(mRealtimeStart);
1174 out.writeLong(mUnpluggedUptime);
1175 out.writeLong(mUnpluggedRealtime);
1180 * State for keeping track of counting information.
1182 public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
1183 final AtomicInteger mCount = new AtomicInteger();
1184 final TimeBase mTimeBase;
1186 int mUnpluggedCount;
1189 public Counter(TimeBase timeBase, Parcel in) {
1190 mTimeBase = timeBase;
1191 mPluggedCount = in.readInt();
1192 mCount.set(mPluggedCount);
1193 mLoadedCount = in.readInt();
1194 mUnpluggedCount = in.readInt();
1198 public Counter(TimeBase timeBase) {
1199 mTimeBase = timeBase;
1203 public void writeToParcel(Parcel out) {
1204 out.writeInt(mCount.get());
1205 out.writeInt(mLoadedCount);
1206 out.writeInt(mUnpluggedCount);
1210 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1211 mUnpluggedCount = mPluggedCount;
1215 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1216 mPluggedCount = mCount.get();
1220 * Writes a possibly null Counter to a Parcel.
1222 * @param out the Parcel to be written to.
1223 * @param counter a Counter, or null.
1225 public static void writeCounterToParcel(Parcel out, @Nullable Counter counter) {
1226 if (counter == null) {
1227 out.writeInt(0); // indicates null
1230 out.writeInt(1); // indicates non-null
1232 counter.writeToParcel(out);
1236 * Reads a Counter that was written using {@link #writeCounterToParcel(Parcel, Counter)}.
1237 * @param timeBase the timebase to assign to the Counter
1238 * @param in the parcel to read from
1239 * @return the Counter or null.
1241 public static @Nullable Counter readCounterFromParcel(TimeBase timeBase, Parcel in) {
1242 if (in.readInt() == 0) {
1245 return new Counter(timeBase, in);
1249 public int getCountLocked(int which) {
1250 int val = mCount.get();
1251 if (which == STATS_SINCE_UNPLUGGED) {
1252 val -= mUnpluggedCount;
1253 } else if (which != STATS_SINCE_CHARGED) {
1254 val -= mLoadedCount;
1260 public void logState(Printer pw, String prefix) {
1261 pw.println(prefix + "mCount=" + mCount.get()
1262 + " mLoadedCount=" + mLoadedCount
1263 + " mUnpluggedCount=" + mUnpluggedCount
1264 + " mPluggedCount=" + mPluggedCount);
1267 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
1268 public void stepAtomic() {
1269 if (mTimeBase.isRunning()) {
1270 mCount.incrementAndGet();
1274 void addAtomic(int delta) {
1275 if (mTimeBase.isRunning()) {
1276 mCount.addAndGet(delta);
1281 * Clear state of this counter.
1283 void reset(boolean detachIfReset) {
1285 mLoadedCount = mPluggedCount = mUnpluggedCount = 0;
1286 if (detachIfReset) {
1292 mTimeBase.remove(this);
1295 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
1296 public void writeSummaryFromParcelLocked(Parcel out) {
1297 int count = mCount.get();
1298 out.writeInt(count);
1301 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
1302 public void readSummaryFromParcelLocked(Parcel in) {
1303 mLoadedCount = in.readInt();
1304 mCount.set(mLoadedCount);
1305 mUnpluggedCount = mPluggedCount = mLoadedCount;
1310 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs {
1311 final TimeBase mTimeBase;
1312 public long[] mCounts;
1313 public long[] mLoadedCounts;
1314 public long[] mUnpluggedCounts;
1316 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
1317 mTimeBase = timeBase;
1318 mCounts = in.createLongArray();
1319 mLoadedCounts = in.createLongArray();
1320 mUnpluggedCounts = in.createLongArray();
1324 public LongSamplingCounterArray(TimeBase timeBase) {
1325 mTimeBase = timeBase;
1329 private void writeToParcel(Parcel out) {
1330 out.writeLongArray(mCounts);
1331 out.writeLongArray(mLoadedCounts);
1332 out.writeLongArray(mUnpluggedCounts);
1336 public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) {
1337 mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
1341 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1345 public long[] getCountsLocked(int which) {
1346 long[] val = copyArray(mCounts, null);
1347 if (which == STATS_SINCE_UNPLUGGED) {
1348 subtract(val, mUnpluggedCounts);
1349 } else if (which != STATS_SINCE_CHARGED) {
1350 subtract(val, mLoadedCounts);
1356 public void logState(Printer pw, String prefix) {
1357 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)
1358 + " mLoadedCounts=" + Arrays.toString(mLoadedCounts)
1359 + " mUnpluggedCounts=" + Arrays.toString(mUnpluggedCounts));
1362 public void addCountLocked(long[] counts) {
1363 addCountLocked(counts, mTimeBase.isRunning());
1366 public void addCountLocked(long[] counts, boolean isRunning) {
1367 if (counts == null) {
1371 if (mCounts == null) {
1372 mCounts = new long[counts.length];
1374 for (int i = 0; i < counts.length; ++i) {
1375 mCounts[i] += counts[i];
1380 public int getSize() {
1381 return mCounts == null ? 0 : mCounts.length;
1385 * Clear state of this counter.
1387 public void reset(boolean detachIfReset) {
1388 fillArray(mCounts, 0);
1389 fillArray(mLoadedCounts, 0);
1390 fillArray(mUnpluggedCounts, 0);
1391 if (detachIfReset) {
1396 public void detach() {
1397 mTimeBase.remove(this);
1400 private void writeSummaryToParcelLocked(Parcel out) {
1401 out.writeLongArray(mCounts);
1404 private void readSummaryFromParcelLocked(Parcel in) {
1405 mCounts = in.createLongArray();
1406 mLoadedCounts = copyArray(mCounts, mLoadedCounts);
1407 mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
1410 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) {
1411 if (counterArray != null) {
1413 counterArray.writeToParcel(out);
1419 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) {
1420 if (in.readInt() != 0) {
1421 return new LongSamplingCounterArray(timeBase, in);
1427 public static void writeSummaryToParcelLocked(Parcel out,
1428 LongSamplingCounterArray counterArray) {
1429 if (counterArray != null) {
1431 counterArray.writeSummaryToParcelLocked(out);
1437 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in,
1438 TimeBase timeBase) {
1439 if (in.readInt() != 0) {
1440 final LongSamplingCounterArray counterArray
1441 = new LongSamplingCounterArray(timeBase);
1442 counterArray.readSummaryFromParcelLocked(in);
1443 return counterArray;
1449 private static void fillArray(long[] a, long val) {
1451 Arrays.fill(a, val);
1455 private static void subtract(@NonNull long[] val, long[] toSubtract) {
1456 if (toSubtract == null) {
1459 for (int i = 0; i < val.length; i++) {
1460 val[i] -= toSubtract[i];
1464 private static long[] copyArray(long[] src, long[] dest) {
1469 dest = new long[src.length];
1471 System.arraycopy(src, 0, dest, 0, src.length);
1477 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
1478 final TimeBase mTimeBase;
1481 long mUnpluggedCount;
1483 LongSamplingCounter(TimeBase timeBase, Parcel in) {
1484 mTimeBase = timeBase;
1485 mCount = in.readLong();
1486 mLoadedCount = in.readLong();
1487 mUnpluggedCount = in.readLong();
1491 LongSamplingCounter(TimeBase timeBase) {
1492 mTimeBase = timeBase;
1496 public void writeToParcel(Parcel out) {
1497 out.writeLong(mCount);
1498 out.writeLong(mLoadedCount);
1499 out.writeLong(mUnpluggedCount);
1503 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1504 mUnpluggedCount = mCount;
1508 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1511 public long getCountLocked(int which) {
1513 if (which == STATS_SINCE_UNPLUGGED) {
1514 val -= mUnpluggedCount;
1515 } else if (which != STATS_SINCE_CHARGED) {
1516 val -= mLoadedCount;
1522 public void logState(Printer pw, String prefix) {
1523 pw.println(prefix + "mCount=" + mCount
1524 + " mLoadedCount=" + mLoadedCount
1525 + " mUnpluggedCount=" + mUnpluggedCount);
1528 void addCountLocked(long count) {
1529 addCountLocked(count, mTimeBase.isRunning());
1532 void addCountLocked(long count, boolean isRunning) {
1539 * Clear state of this counter.
1541 void reset(boolean detachIfReset) {
1543 mLoadedCount = mUnpluggedCount = 0;
1544 if (detachIfReset) {
1550 mTimeBase.remove(this);
1553 void writeSummaryFromParcelLocked(Parcel out) {
1554 out.writeLong(mCount);
1557 void readSummaryFromParcelLocked(Parcel in) {
1558 mLoadedCount = in.readLong();
1559 mCount = mLoadedCount;
1560 mUnpluggedCount = mLoadedCount;
1565 * State for keeping track of timing information.
1567 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
1568 protected final Clocks mClocks;
1569 protected final int mType;
1570 protected final TimeBase mTimeBase;
1572 protected int mCount;
1573 protected int mLoadedCount;
1574 protected int mLastCount;
1575 protected int mUnpluggedCount;
1577 // Times are in microseconds for better accuracy when dividing by the
1578 // lock count, and are in "battery realtime" units.
1581 * The total time we have accumulated since the start of the original
1582 * boot, to the last time something interesting happened in the
1585 protected long mTotalTime;
1588 * The total time we loaded for the previous runs. Subtract this from
1589 * mTotalTime to find the time for the current run of the system.
1591 protected long mLoadedTime;
1594 * The run time of the last run of the system, as loaded from the
1597 protected long mLastTime;
1600 * The value of mTotalTime when unplug() was last called. Subtract
1601 * this from mTotalTime to find the time since the last unplug from
1604 protected long mUnpluggedTime;
1607 * The total time this timer has been running until the latest mark has been set.
1608 * Subtract this from mTotalTime to get the time spent running since the mark was set.
1610 protected long mTimeBeforeMark;
1613 * Constructs from a parcel.
1618 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) {
1621 mTimeBase = timeBase;
1623 mCount = in.readInt();
1624 mLoadedCount = in.readInt();
1626 mUnpluggedCount = in.readInt();
1627 mTotalTime = in.readLong();
1628 mLoadedTime = in.readLong();
1630 mUnpluggedTime = in.readLong();
1631 mTimeBeforeMark = in.readLong();
1633 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
1636 public Timer(Clocks clocks, int type, TimeBase timeBase) {
1639 mTimeBase = timeBase;
1643 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
1645 protected abstract int computeCurrentCountLocked();
1648 * Clear state of this timer. Returns true if the timer is inactive
1649 * so can be completely dropped.
1651 public boolean reset(boolean detachIfReset) {
1652 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0;
1653 mCount = mLoadedCount = mLastCount = 0;
1654 if (detachIfReset) {
1660 public void detach() {
1661 mTimeBase.remove(this);
1664 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1665 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
1666 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
1667 out.writeInt(computeCurrentCountLocked());
1668 out.writeInt(mLoadedCount);
1669 out.writeInt(mUnpluggedCount);
1670 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
1671 out.writeLong(mLoadedTime);
1672 out.writeLong(mUnpluggedTime);
1673 out.writeLong(mTimeBeforeMark);
1677 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
1678 if (DEBUG && mType < 0) {
1679 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
1680 + " old mUnpluggedTime=" + mUnpluggedTime
1681 + " old mUnpluggedCount=" + mUnpluggedCount);
1683 mUnpluggedTime = computeRunTimeLocked(baseRealtime);
1684 mUnpluggedCount = computeCurrentCountLocked();
1685 if (DEBUG && mType < 0) {
1686 Log.v(TAG, "unplug #" + mType
1687 + ": new mUnpluggedTime=" + mUnpluggedTime
1688 + " new mUnpluggedCount=" + mUnpluggedCount);
1693 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1694 if (DEBUG && mType < 0) {
1695 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
1696 + " old mTotalTime=" + mTotalTime);
1698 mTotalTime = computeRunTimeLocked(baseRealtime);
1699 mCount = computeCurrentCountLocked();
1700 if (DEBUG && mType < 0) {
1701 Log.v(TAG, "plug #" + mType
1702 + ": new mTotalTime=" + mTotalTime);
1707 * Writes a possibly null Timer to a Parcel.
1709 * @param out the Parcel to be written to.
1710 * @param timer a Timer, or null.
1712 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
1713 if (timer == null) {
1714 out.writeInt(0); // indicates null
1717 out.writeInt(1); // indicates non-null
1719 timer.writeToParcel(out, elapsedRealtimeUs);
1723 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
1724 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1725 if (which == STATS_SINCE_UNPLUGGED) {
1726 val -= mUnpluggedTime;
1727 } else if (which != STATS_SINCE_CHARGED) {
1735 public int getCountLocked(int which) {
1736 int val = computeCurrentCountLocked();
1737 if (which == STATS_SINCE_UNPLUGGED) {
1738 val -= mUnpluggedCount;
1739 } else if (which != STATS_SINCE_CHARGED) {
1740 val -= mLoadedCount;
1747 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) {
1748 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1749 return val - mTimeBeforeMark;
1753 public void logState(Printer pw, String prefix) {
1754 pw.println(prefix + "mCount=" + mCount
1755 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
1756 + " mUnpluggedCount=" + mUnpluggedCount);
1757 pw.println(prefix + "mTotalTime=" + mTotalTime
1758 + " mLoadedTime=" + mLoadedTime);
1759 pw.println(prefix + "mLastTime=" + mLastTime
1760 + " mUnpluggedTime=" + mUnpluggedTime);
1764 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
1765 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1766 out.writeLong(runTime);
1767 out.writeInt(computeCurrentCountLocked());
1770 public void readSummaryFromParcelLocked(Parcel in) {
1771 // Multiply by 1000 for backwards compatibility
1772 mTotalTime = mLoadedTime = in.readLong();
1774 mUnpluggedTime = mTotalTime;
1775 mCount = mLoadedCount = in.readInt();
1777 mUnpluggedCount = mCount;
1779 // When reading the summary, we set the mark to be the latest information.
1780 mTimeBeforeMark = mTotalTime;
1785 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)}
1786 * method. The state of the timer according to its {@link TimeBase} will determine how much
1787 * of the value is recorded.
1789 * If the value being recorded resets, {@link #endSample()} can be called in order to
1790 * account for the change. If the value passed in to {@link #update(long, int)} decreased
1791 * between calls, the {@link #endSample()} is automatically called and the new value is
1792 * expected to increase monotonically from that point on.
1794 public static class SamplingTimer extends Timer {
1797 * The most recent reported count from /proc/wakelocks.
1799 int mCurrentReportedCount;
1802 * The reported count from /proc/wakelocks when unplug() was last
1805 int mUnpluggedReportedCount;
1808 * The most recent reported total_time from /proc/wakelocks.
1810 long mCurrentReportedTotalTime;
1814 * The reported total_time from /proc/wakelocks when unplug() was last
1817 long mUnpluggedReportedTotalTime;
1820 * Whether we are currently in a discharge cycle.
1822 boolean mTimeBaseRunning;
1825 * Whether we are currently recording reported values.
1827 boolean mTrackingReportedValues;
1830 * A sequence counter, incremented once for each update of the stats.
1835 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) {
1836 super(clocks, 0, timeBase, in);
1837 mCurrentReportedCount = in.readInt();
1838 mUnpluggedReportedCount = in.readInt();
1839 mCurrentReportedTotalTime = in.readLong();
1840 mUnpluggedReportedTotalTime = in.readLong();
1841 mTrackingReportedValues = in.readInt() == 1;
1842 mTimeBaseRunning = timeBase.isRunning();
1846 public SamplingTimer(Clocks clocks, TimeBase timeBase) {
1847 super(clocks, 0, timeBase);
1848 mTrackingReportedValues = false;
1849 mTimeBaseRunning = timeBase.isRunning();
1853 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to
1854 * be less than the values used for a previous invocation.
1856 public void endSample() {
1857 mTotalTime = computeRunTimeLocked(0 /* unused by us */);
1858 mCount = computeCurrentCountLocked();
1859 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0;
1860 mUnpluggedReportedCount = mCurrentReportedCount = 0;
1863 public void setUpdateVersion(int version) {
1864 mUpdateVersion = version;
1867 public int getUpdateVersion() {
1868 return mUpdateVersion;
1872 * Updates the current recorded values. These are meant to be monotonically increasing
1873 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}.
1875 * If the values being recorded have been reset, the monotonically increasing requirement
1876 * will be broken. In this case, {@link #endSample()} is automatically called and
1877 * the total value of totalTime and count are recorded, starting a new monotonically
1878 * increasing sample.
1880 * @param totalTime total time of sample in microseconds.
1881 * @param count total number of times the event being sampled occurred.
1883 public void update(long totalTime, int count) {
1884 if (mTimeBaseRunning && !mTrackingReportedValues) {
1885 // Updating the reported value for the first time.
1886 mUnpluggedReportedTotalTime = totalTime;
1887 mUnpluggedReportedCount = count;
1890 mTrackingReportedValues = true;
1892 if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) {
1896 mCurrentReportedTotalTime = totalTime;
1897 mCurrentReportedCount = count;
1901 * Adds deltaTime and deltaCount to the current sample.
1903 * @param deltaTime additional time recorded since the last sampled event, in microseconds.
1904 * @param deltaCount additional number of times the event being sampled occurred.
1906 public void add(long deltaTime, int deltaCount) {
1907 update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount);
1911 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1912 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
1913 if (mTrackingReportedValues) {
1914 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
1915 mUnpluggedReportedCount = mCurrentReportedCount;
1917 mTimeBaseRunning = true;
1921 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1922 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1923 mTimeBaseRunning = false;
1927 public void logState(Printer pw, String prefix) {
1928 super.logState(pw, prefix);
1929 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
1930 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
1931 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
1932 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
1936 protected long computeRunTimeLocked(long curBatteryRealtime) {
1937 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
1938 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
1942 protected int computeCurrentCountLocked() {
1943 return mCount + (mTimeBaseRunning && mTrackingReportedValues
1944 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
1948 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1949 super.writeToParcel(out, elapsedRealtimeUs);
1950 out.writeInt(mCurrentReportedCount);
1951 out.writeInt(mUnpluggedReportedCount);
1952 out.writeLong(mCurrentReportedTotalTime);
1953 out.writeLong(mUnpluggedReportedTotalTime);
1954 out.writeInt(mTrackingReportedValues ? 1 : 0);
1958 public boolean reset(boolean detachIfReset) {
1959 super.reset(detachIfReset);
1960 mTrackingReportedValues = false;
1961 mUnpluggedReportedTotalTime = 0;
1962 mUnpluggedReportedCount = 0;
1968 * A timer that increments in batches. It does not run for durations, but just jumps
1969 * for a pre-determined amount.
1971 public static class BatchTimer extends Timer {
1975 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
1977 long mLastAddedTime;
1980 * The last duration that we added to the timer. This is in microseconds.
1982 long mLastAddedDuration;
1985 * Whether we are currently in a discharge cycle.
1987 boolean mInDischarge;
1989 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) {
1990 super(clocks, type, timeBase, in);
1992 mLastAddedTime = in.readLong();
1993 mLastAddedDuration = in.readLong();
1994 mInDischarge = timeBase.isRunning();
1997 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) {
1998 super(clocks, type, timeBase);
2000 mInDischarge = timeBase.isRunning();
2004 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
2005 super.writeToParcel(out, elapsedRealtimeUs);
2006 out.writeLong(mLastAddedTime);
2007 out.writeLong(mLastAddedDuration);
2011 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
2012 recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false);
2013 mInDischarge = false;
2014 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
2018 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
2019 recomputeLastDuration(elapsedRealtime, false);
2020 mInDischarge = true;
2021 // If we are still within the last added duration, then re-added whatever remains.
2022 if (mLastAddedTime == elapsedRealtime) {
2023 mTotalTime += mLastAddedDuration;
2025 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
2029 public void logState(Printer pw, String prefix) {
2030 super.logState(pw, prefix);
2031 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
2032 + " mLastAddedDuration=" + mLastAddedDuration);
2035 private long computeOverage(long curTime) {
2036 if (mLastAddedTime > 0) {
2037 return mLastTime + mLastAddedDuration - curTime;
2042 private void recomputeLastDuration(long curTime, boolean abort) {
2043 final long overage = computeOverage(curTime);
2045 // Aborting before the duration ran out -- roll back the remaining
2046 // duration. Only do this if currently discharging; otherwise we didn't
2047 // actually add the time.
2049 mTotalTime -= overage;
2054 mLastAddedTime = curTime;
2055 mLastAddedDuration -= overage;
2060 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
2061 final long now = mClocks.elapsedRealtime() * 1000;
2062 recomputeLastDuration(now, true);
2063 mLastAddedTime = now;
2064 mLastAddedDuration = durationMillis * 1000;
2066 mTotalTime += mLastAddedDuration;
2071 public void abortLastDuration(BatteryStatsImpl stats) {
2072 final long now = mClocks.elapsedRealtime() * 1000;
2073 recomputeLastDuration(now, true);
2077 protected int computeCurrentCountLocked() {
2082 protected long computeRunTimeLocked(long curBatteryRealtime) {
2083 final long overage = computeOverage(mClocks.elapsedRealtime() * 1000);
2085 return mTotalTime = overage;
2091 public boolean reset(boolean detachIfReset) {
2092 final long now = mClocks.elapsedRealtime() * 1000;
2093 recomputeLastDuration(now, true);
2094 boolean stillActive = mLastAddedTime == now;
2095 super.reset(!stillActive && detachIfReset);
2096 return !stillActive;
2102 * A StopwatchTimer that also tracks the total and max individual
2103 * time spent active according to the given timebase. Whereas
2104 * StopwatchTimer apportions the time amongst all in the pool,
2105 * the total and max durations are not apportioned.
2107 public static class DurationTimer extends StopwatchTimer {
2109 * The time (in ms) that the timer was last acquired or the time base
2110 * last (re-)started. Increasing the nesting depth does not reset this time.
2112 * -1 if the timer is currently not running or the time base is not running.
2114 * If written to a parcel, the start time is reset, as is mNesting in the base class
2117 long mStartTimeMs = -1;
2120 * The longest time period (in ms) that the timer has been active. Not pooled.
2122 long mMaxDurationMs;
2125 * The time (in ms) that that the timer has been active since most recent
2126 * stopRunningLocked() or reset(). Not pooled.
2128 long mCurrentDurationMs;
2131 * The total time (in ms) that that the timer has been active since most recent reset()
2132 * prior to the current startRunningLocked. This is the sum of all past currentDurations
2133 * (but not including the present currentDuration) since reset. Not pooled.
2135 long mTotalDurationMs;
2137 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2138 TimeBase timeBase, Parcel in) {
2139 super(clocks, uid, type, timerPool, timeBase, in);
2140 mMaxDurationMs = in.readLong();
2141 mTotalDurationMs = in.readLong();
2142 mCurrentDurationMs = in.readLong();
2145 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2146 TimeBase timeBase) {
2147 super(clocks, uid, type, timerPool, timeBase);
2151 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
2152 super.writeToParcel(out, elapsedRealtimeUs);
2153 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000));
2154 out.writeLong(mTotalDurationMs);
2155 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000));
2159 * Write the summary to the parcel.
2161 * Since the time base is probably meaningless after we come back, reading
2162 * from this will have the effect of stopping the timer. So here all we write
2163 * is the max and total durations.
2166 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
2167 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
2168 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000));
2169 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000));
2173 * Read the summary parcel.
2175 * Has the side effect of stopping the timer.
2178 public void readSummaryFromParcelLocked(Parcel in) {
2179 super.readSummaryFromParcelLocked(in);
2180 mMaxDurationMs = in.readLong();
2181 mTotalDurationMs = in.readLong();
2183 mCurrentDurationMs = 0;
2187 * The TimeBase time started (again).
2189 * If the timer is also running, store the start time.
2191 public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) {
2192 super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime);
2194 mStartTimeMs = baseRealtime / 1000;
2199 * The TimeBase stopped running.
2201 * If the timer is running, add the duration into mCurrentDurationMs.
2204 public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) {
2205 super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs);
2207 // baseRealtimeUs has already been converted to the timebase's realtime.
2208 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs;
2214 public void logState(Printer pw, String prefix) {
2215 super.logState(pw, prefix);
2219 public void startRunningLocked(long elapsedRealtimeMs) {
2220 super.startRunningLocked(elapsedRealtimeMs);
2221 if (mNesting == 1 && mTimeBase.isRunning()) {
2223 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000;
2228 * Decrements the mNesting ref-count on this timer.
2230 * If it actually stopped (mNesting went to 0), then possibly update
2231 * mMaxDuration if the current duration was the longest ever.
2234 public void stopRunningLocked(long elapsedRealtimeMs) {
2235 if (mNesting == 1) {
2236 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs);
2237 mTotalDurationMs += durationMs;
2238 if (durationMs > mMaxDurationMs) {
2239 mMaxDurationMs = durationMs;
2242 mCurrentDurationMs = 0;
2244 // super method decrements mNesting, which getCurrentDurationMsLocked relies on,
2245 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked.
2246 super.stopRunningLocked(elapsedRealtimeMs);
2250 public boolean reset(boolean detachIfReset) {
2251 boolean result = super.reset(detachIfReset);
2253 mTotalDurationMs = 0;
2254 mCurrentDurationMs = 0;
2256 mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime()*1000) / 1000;
2264 * Returns the max duration that this timer has ever seen.
2266 * Note that this time is NOT split between the timers in the timer group that
2267 * this timer is attached to. It is the TOTAL time.
2270 public long getMaxDurationMsLocked(long elapsedRealtimeMs) {
2272 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs);
2273 if (durationMs > mMaxDurationMs) {
2277 return mMaxDurationMs;
2281 * Returns the time since the timer was started.
2282 * Returns 0 if the timer is not currently running.
2284 * Note that this time is NOT split between the timers in the timer group that
2285 * this timer is attached to. It is the TOTAL time.
2287 * Note that if running timer is parceled and unparceled, this method will return
2288 * current duration value at the time of parceling even though timer may not be
2289 * currently running.
2292 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) {
2293 long durationMs = mCurrentDurationMs;
2294 if (mNesting > 0 && mTimeBase.isRunning()) {
2295 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs*1000)/1000)
2302 * Returns the total cumulative duration that this timer has been on since reset().
2303 * If mTimerPool == null, this should be the same
2304 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000.
2306 * Note that this time is NOT split between the timers in the timer group that
2307 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null,
2308 * the result will not be equivalent to getTotalTimeLocked.
2311 public long getTotalDurationMsLocked(long elapsedRealtimeMs) {
2312 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs);
2317 * State for keeping track of timing information.
2319 public static class StopwatchTimer extends Timer {
2321 final ArrayList<StopwatchTimer> mTimerPool;
2326 * The last time at which we updated the timer. If mNesting is > 0,
2327 * subtract this from the current battery time to find the amount of
2328 * time we have been running since we last computed an update.
2333 * The total time at which the timer was acquired, to determine if it
2334 * was actually held for an interesting duration. If time base was not running when timer
2335 * was acquired, will be -1.
2337 long mAcquireTime = -1;
2342 * For partial wake locks, keep track of whether we are in the list
2343 * to consume CPU cycles.
2346 public boolean mInList;
2348 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2349 TimeBase timeBase, Parcel in) {
2350 super(clocks, type, timeBase, in);
2352 mTimerPool = timerPool;
2353 mUpdateTime = in.readLong();
2356 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2357 TimeBase timeBase) {
2358 super(clocks, type, timeBase);
2360 mTimerPool = timerPool;
2363 public void setTimeout(long timeout) {
2367 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
2368 super.writeToParcel(out, elapsedRealtimeUs);
2369 out.writeLong(mUpdateTime);
2372 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
2374 if (DEBUG && mType < 0) {
2375 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
2377 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
2378 mUpdateTime = baseRealtime;
2379 if (DEBUG && mType < 0) {
2380 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
2385 public void logState(Printer pw, String prefix) {
2386 super.logState(pw, prefix);
2387 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
2388 + " mAcquireTime=" + mAcquireTime);
2391 public void startRunningLocked(long elapsedRealtimeMs) {
2392 if (mNesting++ == 0) {
2393 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
2394 mUpdateTime = batteryRealtime;
2395 if (mTimerPool != null) {
2396 // Accumulate time to all currently active timers before adding
2397 // this new one to the pool.
2398 refreshTimersLocked(batteryRealtime, mTimerPool, null);
2399 // Add this timer to the active pool
2400 mTimerPool.add(this);
2402 if (mTimeBase.isRunning()) {
2403 // Increment the count
2405 mAcquireTime = mTotalTime;
2409 if (DEBUG && mType < 0) {
2410 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
2411 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
2412 + " mAcquireTime=" + mAcquireTime);
2417 public boolean isRunningLocked() {
2418 return mNesting > 0;
2421 public void stopRunningLocked(long elapsedRealtimeMs) {
2422 // Ignore attempt to stop a timer that isn't running
2423 if (mNesting == 0) {
2426 if (--mNesting == 0) {
2427 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
2428 if (mTimerPool != null) {
2429 // Accumulate time to all active counters, scaled by the total
2430 // active in the pool, before taking this one out of the pool.
2431 refreshTimersLocked(batteryRealtime, mTimerPool, null);
2432 // Remove this timer from the active pool
2433 mTimerPool.remove(this);
2436 mTotalTime = computeRunTimeLocked(batteryRealtime);
2440 if (DEBUG && mType < 0) {
2441 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
2442 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
2443 + " mAcquireTime=" + mAcquireTime);
2446 if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) {
2447 // If there was no change in the time, then discard this
2448 // count. A somewhat cheezy strategy, but hey.
2454 public void stopAllRunningLocked(long elapsedRealtimeMs) {
2457 stopRunningLocked(elapsedRealtimeMs);
2461 // Update the total time for all other running Timers with the same type as this Timer
2462 // due to a change in timer count
2463 private static long refreshTimersLocked(long batteryRealtime,
2464 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
2466 final int N = pool.size();
2467 for (int i=N-1; i>= 0; i--) {
2468 final StopwatchTimer t = pool.get(i);
2469 long heldTime = batteryRealtime - t.mUpdateTime;
2471 final long myTime = heldTime / N;
2475 t.mTotalTime += myTime;
2477 t.mUpdateTime = batteryRealtime;
2483 protected long computeRunTimeLocked(long curBatteryRealtime) {
2484 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
2485 curBatteryRealtime = mUpdateTime + mTimeout;
2487 return mTotalTime + (mNesting > 0
2488 ? (curBatteryRealtime - mUpdateTime)
2489 / (mTimerPool != null ? mTimerPool.size() : 1)
2494 protected int computeCurrentCountLocked() {
2499 public boolean reset(boolean detachIfReset) {
2500 boolean canDetach = mNesting <= 0;
2501 super.reset(canDetach && detachIfReset);
2503 mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000);
2505 mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later.
2510 public void detach() {
2512 if (mTimerPool != null) {
2513 mTimerPool.remove(this);
2518 public void readSummaryFromParcelLocked(Parcel in) {
2519 super.readSummaryFromParcelLocked(in);
2524 * Set the mark so that we can query later for the total time the timer has
2525 * accumulated since this point. The timer can be running or not.
2527 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds.
2529 public void setMark(long elapsedRealtimeMs) {
2530 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
2533 if (mTimerPool != null) {
2534 refreshTimersLocked(batteryRealtime, mTimerPool, this);
2536 mTotalTime += batteryRealtime - mUpdateTime;
2537 mUpdateTime = batteryRealtime;
2540 mTimeBeforeMark = mTotalTime;
2545 * State for keeping track of two DurationTimers with different TimeBases, presumably where one
2546 * TimeBase is effectively a subset of the other.
2548 public static class DualTimer extends DurationTimer {
2549 // This class both is a DurationTimer and also holds a second DurationTimer.
2550 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a
2551 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for
2552 // STATS_SINCE_CHARGED).
2553 // mSubTimer typically tracks only part of the total time, such as background time, as
2554 // determined by a subTimeBase. It is NOT pooled.
2555 private final DurationTimer mSubTimer;
2558 * Creates a DualTimer to hold a main timer (this) and a mSubTimer.
2559 * The main timer (this) is based on the given timeBase and timerPool.
2560 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if
2561 * the main timer is.
2563 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2564 TimeBase timeBase, TimeBase subTimeBase, Parcel in) {
2565 super(clocks, uid, type, timerPool, timeBase, in);
2566 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in);
2570 * Creates a DualTimer to hold a main timer (this) and a mSubTimer.
2571 * The main timer (this) is based on the given timeBase and timerPool.
2572 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if
2573 * the main timer is.
2575 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2576 TimeBase timeBase, TimeBase subTimeBase) {
2577 super(clocks, uid, type, timerPool, timeBase);
2578 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase);
2581 /** Get the secondary timer. */
2583 public DurationTimer getSubTimer() {
2588 public void startRunningLocked(long elapsedRealtimeMs) {
2589 super.startRunningLocked(elapsedRealtimeMs);
2590 mSubTimer.startRunningLocked(elapsedRealtimeMs);
2594 public void stopRunningLocked(long elapsedRealtimeMs) {
2595 super.stopRunningLocked(elapsedRealtimeMs);
2596 mSubTimer.stopRunningLocked(elapsedRealtimeMs);
2600 public void stopAllRunningLocked(long elapsedRealtimeMs) {
2601 super.stopAllRunningLocked(elapsedRealtimeMs);
2602 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs);
2606 public boolean reset(boolean detachIfReset) {
2607 boolean active = false;
2608 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach().
2609 active |= !mSubTimer.reset(false);
2610 active |= !super.reset(detachIfReset);
2615 public void detach() {
2621 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
2622 super.writeToParcel(out, elapsedRealtimeUs);
2623 mSubTimer.writeToParcel(out, elapsedRealtimeUs);
2627 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
2628 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
2629 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
2633 public void readSummaryFromParcelLocked(Parcel in) {
2634 super.readSummaryFromParcelLocked(in);
2635 mSubTimer.readSummaryFromParcelLocked(in);
2640 public abstract class OverflowArrayMap<T> {
2641 private static final String OVERFLOW_NAME = "*overflow*";
2644 final ArrayMap<String, T> mMap = new ArrayMap<>();
2646 ArrayMap<String, MutableInt> mActiveOverflow;
2647 long mLastOverflowTime;
2648 long mLastOverflowFinishTime;
2649 long mLastClearTime;
2650 long mLastCleanupTime;
2652 public OverflowArrayMap(int uid) {
2656 public ArrayMap<String, T> getMap() {
2660 public void clear() {
2661 mLastClearTime = SystemClock.elapsedRealtime();
2663 mCurOverflow = null;
2664 mActiveOverflow = null;
2667 public void add(String name, T obj) {
2671 mMap.put(name, obj);
2672 if (OVERFLOW_NAME.equals(name)) {
2677 public void cleanup() {
2678 mLastCleanupTime = SystemClock.elapsedRealtime();
2679 if (mActiveOverflow != null) {
2680 if (mActiveOverflow.size() == 0) {
2681 mActiveOverflow = null;
2684 if (mActiveOverflow == null) {
2685 // There is no currently active overflow, so we should no longer have
2686 // an overflow entry.
2687 if (mMap.containsKey(OVERFLOW_NAME)) {
2688 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry "
2689 + mMap.get(OVERFLOW_NAME));
2690 mMap.remove(OVERFLOW_NAME);
2692 mCurOverflow = null;
2694 // There is currently active overflow, so we should still have an overflow entry.
2695 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) {
2696 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur="
2697 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME));
2702 public T startObject(String name) {
2706 T obj = mMap.get(name);
2711 // No object exists for the given name, but do we currently have it
2712 // running as part of the overflow?
2713 if (mActiveOverflow != null) {
2714 MutableInt over = mActiveOverflow.get(name);
2716 // We are already actively counting this name in the overflow object.
2719 // Shouldn't be here, but we'll try to recover.
2720 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow");
2721 obj = mCurOverflow = instantiateObject();
2722 mMap.put(OVERFLOW_NAME, obj);
2729 // No object exists for given name nor in the overflow; we need to make
2731 final int N = mMap.size();
2732 if (N >= MAX_WAKELOCKS_PER_UID) {
2733 // Went over the limit on number of objects to track; this one goes
2734 // in to the overflow.
2737 // Need to start overflow now...
2738 obj = mCurOverflow = instantiateObject();
2739 mMap.put(OVERFLOW_NAME, obj);
2741 if (mActiveOverflow == null) {
2742 mActiveOverflow = new ArrayMap<>();
2744 mActiveOverflow.put(name, new MutableInt(1));
2745 mLastOverflowTime = SystemClock.elapsedRealtime();
2749 // Normal case where we just need to make a new object.
2750 obj = instantiateObject();
2751 mMap.put(name, obj);
2755 public T stopObject(String name) {
2759 T obj = mMap.get(name);
2764 // No object exists for the given name, but do we currently have it
2765 // running as part of the overflow?
2766 if (mActiveOverflow != null) {
2767 MutableInt over = mActiveOverflow.get(name);
2769 // We are already actively counting this name in the overflow object.
2773 if (over.value <= 0) {
2774 mActiveOverflow.remove(name);
2775 mLastOverflowFinishTime = SystemClock.elapsedRealtime();
2782 // Huh, they are stopping an active operation but we can't find one!
2784 StringBuilder sb = new StringBuilder();
2785 sb.append("Unable to find object for ");
2787 sb.append(" in uid ");
2789 sb.append(" mapsize=");
2790 sb.append(mMap.size());
2791 sb.append(" activeoverflow=");
2792 sb.append(mActiveOverflow);
2793 sb.append(" curoverflow=");
2794 sb.append(mCurOverflow);
2795 long now = SystemClock.elapsedRealtime();
2796 if (mLastOverflowTime != 0) {
2797 sb.append(" lastOverflowTime=");
2798 TimeUtils.formatDuration(mLastOverflowTime-now, sb);
2800 if (mLastOverflowFinishTime != 0) {
2801 sb.append(" lastOverflowFinishTime=");
2802 TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb);
2804 if (mLastClearTime != 0) {
2805 sb.append(" lastClearTime=");
2806 TimeUtils.formatDuration(mLastClearTime-now, sb);
2808 if (mLastCleanupTime != 0) {
2809 sb.append(" lastCleanupTime=");
2810 TimeUtils.formatDuration(mLastCleanupTime-now, sb);
2812 Slog.wtf(TAG, sb.toString());
2816 public abstract T instantiateObject();
2819 public static class ControllerActivityCounterImpl extends ControllerActivityCounter
2820 implements Parcelable {
2821 private final LongSamplingCounter mIdleTimeMillis;
2822 private final LongSamplingCounter mScanTimeMillis;
2823 private final LongSamplingCounter mRxTimeMillis;
2824 private final LongSamplingCounter[] mTxTimeMillis;
2825 private final LongSamplingCounter mPowerDrainMaMs;
2827 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) {
2828 mIdleTimeMillis = new LongSamplingCounter(timeBase);
2829 mScanTimeMillis = new LongSamplingCounter(timeBase);
2830 mRxTimeMillis = new LongSamplingCounter(timeBase);
2831 mTxTimeMillis = new LongSamplingCounter[numTxStates];
2832 for (int i = 0; i < numTxStates; i++) {
2833 mTxTimeMillis[i] = new LongSamplingCounter(timeBase);
2835 mPowerDrainMaMs = new LongSamplingCounter(timeBase);
2838 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) {
2839 mIdleTimeMillis = new LongSamplingCounter(timeBase, in);
2840 mScanTimeMillis = new LongSamplingCounter(timeBase, in);
2841 mRxTimeMillis = new LongSamplingCounter(timeBase, in);
2842 final int recordedTxStates = in.readInt();
2843 if (recordedTxStates != numTxStates) {
2844 throw new ParcelFormatException("inconsistent tx state lengths");
2847 mTxTimeMillis = new LongSamplingCounter[numTxStates];
2848 for (int i = 0; i < numTxStates; i++) {
2849 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in);
2851 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in);
2854 public void readSummaryFromParcel(Parcel in) {
2855 mIdleTimeMillis.readSummaryFromParcelLocked(in);
2856 mScanTimeMillis.readSummaryFromParcelLocked(in);
2857 mRxTimeMillis.readSummaryFromParcelLocked(in);
2858 final int recordedTxStates = in.readInt();
2859 if (recordedTxStates != mTxTimeMillis.length) {
2860 throw new ParcelFormatException("inconsistent tx state lengths");
2862 for (LongSamplingCounter counter : mTxTimeMillis) {
2863 counter.readSummaryFromParcelLocked(in);
2865 mPowerDrainMaMs.readSummaryFromParcelLocked(in);
2869 public int describeContents() {
2873 public void writeSummaryToParcel(Parcel dest) {
2874 mIdleTimeMillis.writeSummaryFromParcelLocked(dest);
2875 mScanTimeMillis.writeSummaryFromParcelLocked(dest);
2876 mRxTimeMillis.writeSummaryFromParcelLocked(dest);
2877 dest.writeInt(mTxTimeMillis.length);
2878 for (LongSamplingCounter counter : mTxTimeMillis) {
2879 counter.writeSummaryFromParcelLocked(dest);
2881 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest);
2885 public void writeToParcel(Parcel dest, int flags) {
2886 mIdleTimeMillis.writeToParcel(dest);
2887 mScanTimeMillis.writeToParcel(dest);
2888 mRxTimeMillis.writeToParcel(dest);
2889 dest.writeInt(mTxTimeMillis.length);
2890 for (LongSamplingCounter counter : mTxTimeMillis) {
2891 counter.writeToParcel(dest);
2893 mPowerDrainMaMs.writeToParcel(dest);
2896 public void reset(boolean detachIfReset) {
2897 mIdleTimeMillis.reset(detachIfReset);
2898 mScanTimeMillis.reset(detachIfReset);
2899 mRxTimeMillis.reset(detachIfReset);
2900 for (LongSamplingCounter counter : mTxTimeMillis) {
2901 counter.reset(detachIfReset);
2903 mPowerDrainMaMs.reset(detachIfReset);
2906 public void detach() {
2907 mIdleTimeMillis.detach();
2908 mScanTimeMillis.detach();
2909 mRxTimeMillis.detach();
2910 for (LongSamplingCounter counter : mTxTimeMillis) {
2913 mPowerDrainMaMs.detach();
2917 * @return a LongSamplingCounter, measuring time spent in the idle state in
2921 public LongSamplingCounter getIdleTimeCounter() {
2922 return mIdleTimeMillis;
2926 * @return a LongSamplingCounter, measuring time spent in the scan state in
2930 public LongSamplingCounter getScanTimeCounter() {
2931 return mScanTimeMillis;
2935 * @return a LongSamplingCounter, measuring time spent in the receive state in
2939 public LongSamplingCounter getRxTimeCounter() {
2940 return mRxTimeMillis;
2944 * @return a LongSamplingCounter[], measuring time spent in various transmit states in
2948 public LongSamplingCounter[] getTxTimeCounters() {
2949 return mTxTimeMillis;
2953 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS).
2956 public LongSamplingCounter getPowerCounter() {
2957 return mPowerDrainMaMs;
2961 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */
2962 public SamplingTimer getRpmTimerLocked(String name) {
2963 SamplingTimer rpmt = mRpmStats.get(name);
2965 rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase);
2966 mRpmStats.put(name, rpmt);
2971 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */
2972 public SamplingTimer getScreenOffRpmTimerLocked(String name) {
2973 SamplingTimer rpmt = mScreenOffRpmStats.get(name);
2975 rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase);
2976 mScreenOffRpmStats.put(name, rpmt);
2982 * Get the wakeup reason counter, and create a new one if one
2983 * doesn't already exist.
2985 public SamplingTimer getWakeupReasonTimerLocked(String name) {
2986 SamplingTimer timer = mWakeupReasonStats.get(name);
2987 if (timer == null) {
2988 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase);
2989 mWakeupReasonStats.put(name, timer);
2995 * Get the KernelWakelockTimer associated with name, and create a new one if one
2996 * doesn't already exist.
2998 public SamplingTimer getKernelWakelockTimerLocked(String name) {
2999 SamplingTimer kwlt = mKernelWakelockStats.get(name);
3001 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase);
3002 mKernelWakelockStats.put(name, kwlt);
3007 public SamplingTimer getKernelMemoryTimerLocked(long bucket) {
3008 SamplingTimer kmt = mKernelMemoryStats.get(bucket);
3010 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase);
3011 mKernelMemoryStats.put(bucket, kmt);
3016 private int writeHistoryTag(HistoryTag tag) {
3017 Integer idxObj = mHistoryTagPool.get(tag);
3019 if (idxObj != null) {
3022 idx = mNextHistoryTagIdx;
3023 HistoryTag key = new HistoryTag();
3026 mHistoryTagPool.put(key, idx);
3027 mNextHistoryTagIdx++;
3028 mNumHistoryTagChars += key.string.length() + 1;
3033 private void readHistoryTag(int index, HistoryTag tag) {
3034 tag.string = mReadHistoryStrings[index];
3035 tag.uid = mReadHistoryUids[index];
3036 tag.poolIdx = index;
3040 The history delta format uses flags to denote further data in subsequent ints in the parcel.
3042 There is always the first token, which may contain the delta time, or an indicator of
3043 the length of the time (int or long) following this token.
3045 First token: always present,
3047 â–ˆM|L|K|J|I|H|G|Fâ–ˆE|D|C|B|A|T|T|Tâ–ˆT|T|T|T|T|T|T|Tâ–ˆT|T|T|T|T|T|T|Tâ–ˆ
3049 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately
3050 follows containing the time, and 0x7ffff indicates a long immediately follows with the
3052 A: battery level changed and an int follows with battery data.
3053 B: state changed and an int follows with state change data.
3054 C: state2 has changed and an int follows with state2 change data.
3055 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows.
3056 E: event data has changed and an event struct follows.
3057 F: battery charge in coulombs has changed and an int with the charge follows.
3058 G: state flag denoting that the mobile radio was active.
3059 H: state flag denoting that the wifi radio was active.
3060 I: state flag denoting that a wifi scan occurred.
3061 J: state flag denoting that a wifi full lock was held.
3062 K: state flag denoting that the gps was on.
3063 L: state flag denoting that a wakelock was held.
3064 M: state flag denoting that the cpu was running.
3066 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows
3067 with the time delta.
3069 Battery level int: if A in the first token is set,
3071 â–ˆL|L|L|L|L|L|L|Tâ–ˆT|T|T|T|T|T|T|Tâ–ˆT|V|V|V|V|V|V|Vâ–ˆV|V|V|V|V|V|V|Dâ–ˆ
3073 D: indicates that extra history details follow.
3074 V: the battery voltage.
3075 T: the battery temperature.
3076 L: the battery level (out of 100).
3078 State change int: if B in the first token is set,
3080 â–ˆS|S|S|H|H|H|P|Pâ–ˆF|E|D|C|B| | |Aâ–ˆ | | | | | | | â–ˆ | | | | | | | â–ˆ
3082 A: wifi multicast was on.
3083 B: battery was plugged in.
3085 D: phone was scanning for signal.
3087 F: a sensor was active.
3089 State2 change int: if C in the first token is set,
3091 â–ˆM|L|K|J|I|H|H|Gâ–ˆF|E|D|C| | | | â–ˆ | | | | | | | â–ˆ |B|B|B|A|A|A|Aâ–ˆ
3093 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}.
3094 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4.
3095 C: a bluetooth scan was active.
3096 D: the camera was active.
3097 E: bluetooth was on.
3098 F: a phone call was active.
3099 G: the device was charging.
3100 H: 2 bits indicating the device-idle (doze) state: off, light, full
3101 I: the flashlight was on.
3103 K: wifi was running.
3104 L: video was playing.
3105 M: power save mode was on.
3107 Wakelock/wakereason struct: if D in the first token is set,
3108 TODO(adamlesinski): describe wakelock/wakereason struct.
3110 Event struct: if E in the first token is set,
3111 TODO(adamlesinski): describe the event struct.
3113 History step details struct: if D in the battery level int is set,
3114 TODO(adamlesinski): describe the history step details struct.
3116 Battery charge int: if F in the first token is set, an int representing the battery charge
3117 in coulombs follows.
3120 // Part of initial delta int that specifies the time delta.
3121 static final int DELTA_TIME_MASK = 0x7ffff;
3122 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
3123 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
3124 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
3125 // Flag in delta int: a new battery level int follows.
3126 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
3127 // Flag in delta int: a new full state and battery status int follows.
3128 static final int DELTA_STATE_FLAG = 0x00100000;
3129 // Flag in delta int: a new full state2 int follows.
3130 static final int DELTA_STATE2_FLAG = 0x00200000;
3131 // Flag in delta int: contains a wakelock or wakeReason tag.
3132 static final int DELTA_WAKELOCK_FLAG = 0x00400000;
3133 // Flag in delta int: contains an event description.
3134 static final int DELTA_EVENT_FLAG = 0x00800000;
3135 // Flag in delta int: contains the battery charge count in uAh.
3136 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000;
3137 // These upper bits are the frequently changing state bits.
3138 static final int DELTA_STATE_MASK = 0xfe000000;
3140 // These are the pieces of battery state that are packed in to the upper bits of
3141 // the state int that have been packed in to the first delta int. They must fit
3142 // in STATE_BATTERY_MASK.
3143 static final int STATE_BATTERY_MASK = 0xff000000;
3144 static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
3145 static final int STATE_BATTERY_STATUS_SHIFT = 29;
3146 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
3147 static final int STATE_BATTERY_HEALTH_SHIFT = 26;
3148 static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
3149 static final int STATE_BATTERY_PLUG_SHIFT = 24;
3151 // We use the low bit of the battery state int to indicate that we have full details
3152 // from a battery level change.
3153 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001;
3155 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
3156 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
3157 dest.writeInt(DELTA_TIME_ABS);
3158 cur.writeToParcel(dest, 0);
3162 final long deltaTime = cur.time - last.time;
3163 final int lastBatteryLevelInt = buildBatteryLevelInt(last);
3164 final int lastStateInt = buildStateInt(last);
3167 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
3168 deltaTimeToken = DELTA_TIME_LONG;
3169 } else if (deltaTime >= DELTA_TIME_ABS) {
3170 deltaTimeToken = DELTA_TIME_INT;
3172 deltaTimeToken = (int)deltaTime;
3174 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
3175 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel
3176 ? BATTERY_DELTA_LEVEL_FLAG : 0;
3177 final boolean computeStepDetails = includeStepDetails != 0
3178 || mLastHistoryStepDetails == null;
3179 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails;
3180 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
3181 if (batteryLevelIntChanged) {
3182 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
3184 final int stateInt = buildStateInt(cur);
3185 final boolean stateIntChanged = stateInt != lastStateInt;
3186 if (stateIntChanged) {
3187 firstToken |= DELTA_STATE_FLAG;
3189 final boolean state2IntChanged = cur.states2 != last.states2;
3190 if (state2IntChanged) {
3191 firstToken |= DELTA_STATE2_FLAG;
3193 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
3194 firstToken |= DELTA_WAKELOCK_FLAG;
3196 if (cur.eventCode != HistoryItem.EVENT_NONE) {
3197 firstToken |= DELTA_EVENT_FLAG;
3200 final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh;
3201 if (batteryChargeChanged) {
3202 firstToken |= DELTA_BATTERY_CHARGE_FLAG;
3204 dest.writeInt(firstToken);
3205 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
3206 + " deltaTime=" + deltaTime);
3208 if (deltaTimeToken >= DELTA_TIME_INT) {
3209 if (deltaTimeToken == DELTA_TIME_INT) {
3210 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
3211 dest.writeInt((int)deltaTime);
3213 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
3214 dest.writeLong(deltaTime);
3217 if (batteryLevelIntChanged) {
3218 dest.writeInt(batteryLevelInt);
3219 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
3220 + Integer.toHexString(batteryLevelInt)
3221 + " batteryLevel=" + cur.batteryLevel
3222 + " batteryTemp=" + cur.batteryTemperature
3223 + " batteryVolt=" + (int)cur.batteryVoltage);
3225 if (stateIntChanged) {
3226 dest.writeInt(stateInt);
3227 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
3228 + Integer.toHexString(stateInt)
3229 + " batteryStatus=" + cur.batteryStatus
3230 + " batteryHealth=" + cur.batteryHealth
3231 + " batteryPlugType=" + cur.batteryPlugType
3232 + " states=0x" + Integer.toHexString(cur.states));
3234 if (state2IntChanged) {
3235 dest.writeInt(cur.states2);
3236 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
3237 + Integer.toHexString(cur.states2));
3239 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
3241 int wakeReasonIndex;
3242 if (cur.wakelockTag != null) {
3243 wakeLockIndex = writeHistoryTag(cur.wakelockTag);
3244 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
3245 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
3247 wakeLockIndex = 0xffff;
3249 if (cur.wakeReasonTag != null) {
3250 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
3251 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
3252 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
3254 wakeReasonIndex = 0xffff;
3256 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
3258 if (cur.eventCode != HistoryItem.EVENT_NONE) {
3259 int index = writeHistoryTag(cur.eventTag);
3260 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
3261 dest.writeInt(codeAndIndex);
3262 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
3263 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
3264 + cur.eventTag.string);
3266 if (computeStepDetails) {
3267 if (mPlatformIdleStateCallback != null) {
3268 mCurHistoryStepDetails.statPlatformIdleState =
3269 mPlatformIdleStateCallback.getPlatformLowPowerStats();
3270 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" +
3271 mCurHistoryStepDetails.statPlatformIdleState);
3273 mCurHistoryStepDetails.statSubsystemPowerState =
3274 mPlatformIdleStateCallback.getSubsystemLowPowerStats();
3275 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" +
3276 mCurHistoryStepDetails.statSubsystemPowerState);
3279 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
3280 if (includeStepDetails != 0) {
3281 mCurHistoryStepDetails.writeToParcel(dest);
3283 cur.stepDetails = mCurHistoryStepDetails;
3284 mLastHistoryStepDetails = mCurHistoryStepDetails;
3286 cur.stepDetails = null;
3288 if (mLastHistoryStepLevel < cur.batteryLevel) {
3289 mLastHistoryStepDetails = null;
3291 mLastHistoryStepLevel = cur.batteryLevel;
3293 if (batteryChargeChanged) {
3294 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh);
3295 dest.writeInt(cur.batteryChargeUAh);
3299 private int buildBatteryLevelInt(HistoryItem h) {
3300 return ((((int)h.batteryLevel)<<25)&0xfe000000)
3301 | ((((int)h.batteryTemperature)<<15)&0x01ff8000)
3302 | ((((int)h.batteryVoltage)<<1)&0x00007ffe);
3305 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) {
3306 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25);
3307 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15);
3308 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1);
3311 private int buildStateInt(HistoryItem h) {
3313 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
3315 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
3317 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
3320 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
3321 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
3322 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
3323 | (h.states&(~STATE_BATTERY_MASK));
3326 private void computeHistoryStepDetails(final HistoryStepDetails out,
3327 final HistoryStepDetails last) {
3328 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out;
3330 // Perform a CPU update right after we do this collection, so we have started
3331 // collecting good data for the next step.
3332 requestImmediateCpuUpdate();
3335 // We are not generating a delta, so all we need to do is reset the stats
3336 // we will later be doing a delta from.
3337 final int NU = mUidStats.size();
3338 for (int i=0; i<NU; i++) {
3339 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3340 uid.mLastStepUserTime = uid.mCurStepUserTime;
3341 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
3343 mLastStepCpuUserTime = mCurStepCpuUserTime;
3344 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
3345 mLastStepStatUserTime = mCurStepStatUserTime;
3346 mLastStepStatSystemTime = mCurStepStatSystemTime;
3347 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
3348 mLastStepStatIrqTime = mCurStepStatIrqTime;
3349 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
3350 mLastStepStatIdleTime = mCurStepStatIdleTime;
3355 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys="
3356 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime
3357 + " irq=" + mLastStepStatIrqTime + " sirq="
3358 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime);
3359 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys="
3360 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime
3361 + " irq=" + mCurStepStatIrqTime + " sirq="
3362 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime);
3364 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime);
3365 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime);
3366 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime);
3367 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime);
3368 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime);
3369 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime);
3370 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime);
3371 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime);
3372 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1;
3373 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0;
3374 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0;
3375 final int NU = mUidStats.size();
3376 for (int i=0; i<NU; i++) {
3377 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3378 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime);
3379 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime);
3380 final int totalTime = totalUTime + totalSTime;
3381 uid.mLastStepUserTime = uid.mCurStepUserTime;
3382 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
3383 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) {
3386 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) {
3387 out.appCpuUid3 = uid.mUid;
3388 out.appCpuUTime3 = totalUTime;
3389 out.appCpuSTime3 = totalSTime;
3391 out.appCpuUid3 = out.appCpuUid2;
3392 out.appCpuUTime3 = out.appCpuUTime2;
3393 out.appCpuSTime3 = out.appCpuSTime2;
3394 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) {
3395 out.appCpuUid2 = uid.mUid;
3396 out.appCpuUTime2 = totalUTime;
3397 out.appCpuSTime2 = totalSTime;
3399 out.appCpuUid2 = out.appCpuUid1;
3400 out.appCpuUTime2 = out.appCpuUTime1;
3401 out.appCpuSTime2 = out.appCpuSTime1;
3402 out.appCpuUid1 = uid.mUid;
3403 out.appCpuUTime1 = totalUTime;
3404 out.appCpuSTime1 = totalSTime;
3408 mLastStepCpuUserTime = mCurStepCpuUserTime;
3409 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
3410 mLastStepStatUserTime = mCurStepStatUserTime;
3411 mLastStepStatSystemTime = mCurStepStatSystemTime;
3412 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
3413 mLastStepStatIrqTime = mCurStepStatIrqTime;
3414 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
3415 mLastStepStatIdleTime = mCurStepStatIdleTime;
3418 public void readHistoryDelta(Parcel src, HistoryItem cur) {
3419 int firstToken = src.readInt();
3420 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
3421 cur.cmd = HistoryItem.CMD_UPDATE;
3422 cur.numReadInts = 1;
3423 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
3424 + " deltaTimeToken=" + deltaTimeToken);
3426 if (deltaTimeToken < DELTA_TIME_ABS) {
3427 cur.time += deltaTimeToken;
3428 } else if (deltaTimeToken == DELTA_TIME_ABS) {
3429 cur.time = src.readLong();
3430 cur.numReadInts += 2;
3431 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
3432 cur.readFromParcel(src);
3434 } else if (deltaTimeToken == DELTA_TIME_INT) {
3435 int delta = src.readInt();
3437 cur.numReadInts += 1;
3438 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
3440 long delta = src.readLong();
3441 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
3443 cur.numReadInts += 2;
3446 final int batteryLevelInt;
3447 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
3448 batteryLevelInt = src.readInt();
3449 readBatteryLevelInt(batteryLevelInt, cur);
3450 cur.numReadInts += 1;
3451 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
3452 + Integer.toHexString(batteryLevelInt)
3453 + " batteryLevel=" + cur.batteryLevel
3454 + " batteryTemp=" + cur.batteryTemperature
3455 + " batteryVolt=" + (int)cur.batteryVoltage);
3457 batteryLevelInt = 0;
3460 if ((firstToken&DELTA_STATE_FLAG) != 0) {
3461 int stateInt = src.readInt();
3462 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK));
3463 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
3464 & STATE_BATTERY_STATUS_MASK);
3465 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
3466 & STATE_BATTERY_HEALTH_MASK);
3467 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
3468 & STATE_BATTERY_PLUG_MASK);
3469 switch (cur.batteryPlugType) {
3471 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
3474 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
3477 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
3480 cur.numReadInts += 1;
3481 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
3482 + Integer.toHexString(stateInt)
3483 + " batteryStatus=" + cur.batteryStatus
3484 + " batteryHealth=" + cur.batteryHealth
3485 + " batteryPlugType=" + cur.batteryPlugType
3486 + " states=0x" + Integer.toHexString(cur.states));
3488 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK));
3491 if ((firstToken&DELTA_STATE2_FLAG) != 0) {
3492 cur.states2 = src.readInt();
3493 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
3494 + Integer.toHexString(cur.states2));
3497 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
3498 int indexes = src.readInt();
3499 int wakeLockIndex = indexes&0xffff;
3500 int wakeReasonIndex = (indexes>>16)&0xffff;
3501 if (wakeLockIndex != 0xffff) {
3502 cur.wakelockTag = cur.localWakelockTag;
3503 readHistoryTag(wakeLockIndex, cur.wakelockTag);
3504 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
3505 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
3507 cur.wakelockTag = null;
3509 if (wakeReasonIndex != 0xffff) {
3510 cur.wakeReasonTag = cur.localWakeReasonTag;
3511 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
3512 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
3513 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
3515 cur.wakeReasonTag = null;
3517 cur.numReadInts += 1;
3519 cur.wakelockTag = null;
3520 cur.wakeReasonTag = null;
3523 if ((firstToken&DELTA_EVENT_FLAG) != 0) {
3524 cur.eventTag = cur.localEventTag;
3525 final int codeAndIndex = src.readInt();
3526 cur.eventCode = (codeAndIndex&0xffff);
3527 final int index = ((codeAndIndex>>16)&0xffff);
3528 readHistoryTag(index, cur.eventTag);
3529 cur.numReadInts += 1;
3530 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
3531 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
3532 + cur.eventTag.string);
3534 cur.eventCode = HistoryItem.EVENT_NONE;
3537 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) {
3538 cur.stepDetails = mReadHistoryStepDetails;
3539 cur.stepDetails.readFromParcel(src);
3541 cur.stepDetails = null;
3544 if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) {
3545 cur.batteryChargeUAh = src.readInt();
3550 public void commitCurrentHistoryBatchLocked() {
3551 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
3554 void addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur) {
3555 if (!mHaveBatteryLevel || !mRecordingHistory) {
3559 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
3560 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates);
3561 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2);
3562 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
3563 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
3564 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
3565 + Integer.toHexString(diffStates) + " lastDiff="
3566 + Integer.toHexString(lastDiffStates) + " diff2="
3567 + Integer.toHexString(diffStates2) + " lastDiff2="
3568 + Integer.toHexString(lastDiffStates2));
3569 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
3570 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
3571 && (diffStates2&lastDiffStates2) == 0
3572 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
3573 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
3574 && mHistoryLastWritten.stepDetails == null
3575 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
3576 || cur.eventCode == HistoryItem.EVENT_NONE)
3577 && mHistoryLastWritten.batteryLevel == cur.batteryLevel
3578 && mHistoryLastWritten.batteryStatus == cur.batteryStatus
3579 && mHistoryLastWritten.batteryHealth == cur.batteryHealth
3580 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
3581 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
3582 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
3583 // We can merge this new change in with the last one. Merging is
3584 // allowed as long as only the states have changed, and within those states
3585 // as long as no bit has changed both between now and the last entry, as
3586 // well as the last entry and the one before it (so we capture any toggles).
3587 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
3588 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
3589 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
3590 mHistoryBufferLastPos = -1;
3591 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
3592 // If the last written history had a wakelock tag, we need to retain it.
3593 // Note that the condition above made sure that we aren't in a case where
3594 // both it and the current history item have a wakelock tag.
3595 if (mHistoryLastWritten.wakelockTag != null) {
3596 cur.wakelockTag = cur.localWakelockTag;
3597 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
3599 // If the last written history had a wake reason tag, we need to retain it.
3600 // Note that the condition above made sure that we aren't in a case where
3601 // both it and the current history item have a wakelock tag.
3602 if (mHistoryLastWritten.wakeReasonTag != null) {
3603 cur.wakeReasonTag = cur.localWakeReasonTag;
3604 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
3606 // If the last written history had an event, we need to retain it.
3607 // Note that the condition above made sure that we aren't in a case where
3608 // both it and the current history item have an event.
3609 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
3610 cur.eventCode = mHistoryLastWritten.eventCode;
3611 cur.eventTag = cur.localEventTag;
3612 cur.eventTag.setTo(mHistoryLastWritten.eventTag);
3614 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
3617 boolean recordResetDueToOverflow = false;
3618 final int dataSize = mHistoryBuffer.dataSize();
3619 if (dataSize >= MAX_MAX_HISTORY_BUFFER*3) {
3620 // Clients can't deal with history buffers this large. This only
3621 // really happens when the device is on charger and interacted with
3622 // for long periods of time, like in retail mode. Since the device is
3623 // most likely charged, when unplugged, stats would have reset anyways.
3624 // Reset the stats and mark that we overflowed.
3626 resetAllStatsLocked();
3628 // Mark that we want to set *OVERFLOW* event and the RESET:START
3630 recordResetDueToOverflow = true;
3632 } else if (dataSize >= MAX_HISTORY_BUFFER) {
3633 if (!mHistoryOverflow) {
3634 mHistoryOverflow = true;
3635 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur);
3636 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW, cur);
3640 // After overflow, we allow various bit-wise states to settle to 0.
3641 boolean writeAnyway = false;
3642 final int curStates = cur.states & HistoryItem.SETTLE_TO_ZERO_STATES
3643 & mActiveHistoryStates;
3644 if (mHistoryLastWritten.states != curStates) {
3645 // mActiveHistoryStates keeps track of which bits in .states are now being
3647 int old = mActiveHistoryStates;
3648 mActiveHistoryStates &= curStates | ~HistoryItem.SETTLE_TO_ZERO_STATES;
3649 writeAnyway |= old != mActiveHistoryStates;
3651 final int curStates2 = cur.states2 & HistoryItem.SETTLE_TO_ZERO_STATES2
3652 & mActiveHistoryStates2;
3653 if (mHistoryLastWritten.states2 != curStates2) {
3654 // mActiveHistoryStates2 keeps track of which bits in .states2 are now being
3656 int old = mActiveHistoryStates2;
3657 mActiveHistoryStates2 &= curStates2 | ~HistoryItem.SETTLE_TO_ZERO_STATES2;
3658 writeAnyway |= old != mActiveHistoryStates2;
3661 // Once we've reached the maximum number of items, we only
3662 // record changes to the battery level and the most interesting states.
3663 // Once we've reached the maximum maximum number of items, we only
3664 // record changes to the battery level.
3665 if (!writeAnyway && mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
3666 (dataSize >= MAX_MAX_HISTORY_BUFFER
3667 || ((mHistoryLastWritten.states^cur.states)
3668 & HistoryItem.MOST_INTERESTING_STATES) == 0
3669 || ((mHistoryLastWritten.states2^cur.states2)
3670 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) {
3674 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur);
3678 if (dataSize == 0 || recordResetDueToOverflow) {
3679 // The history is currently empty; we need it to start with a time stamp.
3680 cur.currentTime = System.currentTimeMillis();
3681 if (recordResetDueToOverflow) {
3682 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW, cur);
3684 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_RESET, cur);
3686 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur);
3689 private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) {
3690 if (mIteratingHistory) {
3691 throw new IllegalStateException("Can't do this while iterating history!");
3693 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
3694 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
3695 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
3696 mHistoryLastWritten.states &= mActiveHistoryStates;
3697 mHistoryLastWritten.states2 &= mActiveHistoryStates2;
3698 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
3699 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
3700 cur.wakelockTag = null;
3701 cur.wakeReasonTag = null;
3702 cur.eventCode = HistoryItem.EVENT_NONE;
3703 cur.eventTag = null;
3704 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
3705 + " now " + mHistoryBuffer.dataPosition()
3706 + " size is now " + mHistoryBuffer.dataSize());
3709 int mChangedStates = 0;
3710 int mChangedStates2 = 0;
3712 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
3713 if (mTrackRunningHistoryElapsedRealtime != 0) {
3714 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
3715 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
3716 if (diffUptime < (diffElapsed-20)) {
3717 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
3718 mHistoryAddTmp.setTo(mHistoryLastWritten);
3719 mHistoryAddTmp.wakelockTag = null;
3720 mHistoryAddTmp.wakeReasonTag = null;
3721 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
3722 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
3723 addHistoryRecordInnerLocked(wakeElapsedTime, mHistoryAddTmp);
3726 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
3727 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
3728 mTrackRunningHistoryUptime = uptimeMs;
3729 addHistoryRecordInnerLocked(elapsedRealtimeMs, mHistoryCur);
3732 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur) {
3733 addHistoryBufferLocked(elapsedRealtimeMs, cur);
3735 if (!USE_OLD_HISTORY) {
3739 if (!mHaveBatteryLevel || !mRecordingHistory) {
3743 // If the current time is basically the same as the last time,
3744 // and no states have since the last recorded entry changed and
3745 // are now resetting back to their original value, then just collapse
3747 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
3748 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
3749 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0
3750 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) {
3751 // If the current is the same as the one before, then we no
3752 // longer need the entry.
3753 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
3754 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
3755 && mHistoryLastEnd.sameNonEvent(cur)) {
3756 mHistoryLastEnd.next = null;
3757 mHistoryEnd.next = mHistoryCache;
3758 mHistoryCache = mHistoryEnd;
3759 mHistoryEnd = mHistoryLastEnd;
3760 mHistoryLastEnd = null;
3762 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates);
3763 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2);
3764 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
3770 mChangedStates2 = 0;
3772 if (mNumHistoryItems == MAX_HISTORY_ITEMS
3773 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
3774 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW, cur);
3777 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
3778 // Once we've reached the maximum number of items, we only
3779 // record changes to the battery level and the most interesting states.
3780 // Once we've reached the maximum maximum number of items, we only
3781 // record changes to the battery level.
3782 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
3783 == cur.batteryLevel &&
3784 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
3785 || ((mHistoryEnd.states^(cur.states&mActiveHistoryStates))
3786 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
3791 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur);
3794 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
3795 String name, int uid) {
3796 mHistoryCur.eventCode = code;
3797 mHistoryCur.eventTag = mHistoryCur.localEventTag;
3798 mHistoryCur.eventTag.string = name;
3799 mHistoryCur.eventTag.uid = uid;
3800 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
3803 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
3804 HistoryItem rec = mHistoryCache;
3806 mHistoryCache = rec.next;
3808 rec = new HistoryItem();
3810 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
3812 addHistoryRecordLocked(rec);
3815 void addHistoryRecordLocked(HistoryItem rec) {
3818 mHistoryLastEnd = mHistoryEnd;
3819 if (mHistoryEnd != null) {
3820 mHistoryEnd.next = rec;
3823 mHistory = mHistoryEnd = rec;
3827 void clearHistoryLocked() {
3828 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
3829 if (USE_OLD_HISTORY) {
3830 if (mHistory != null) {
3831 mHistoryEnd.next = mHistoryCache;
3832 mHistoryCache = mHistory;
3833 mHistory = mHistoryLastEnd = mHistoryEnd = null;
3835 mNumHistoryItems = 0;
3838 mHistoryBaseTime = 0;
3839 mLastHistoryElapsedRealtime = 0;
3840 mTrackRunningHistoryElapsedRealtime = 0;
3841 mTrackRunningHistoryUptime = 0;
3843 mHistoryBuffer.setDataSize(0);
3844 mHistoryBuffer.setDataPosition(0);
3845 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
3846 mHistoryLastLastWritten.clear();
3847 mHistoryLastWritten.clear();
3848 mHistoryTagPool.clear();
3849 mNextHistoryTagIdx = 0;
3850 mNumHistoryTagChars = 0;
3851 mHistoryBufferLastPos = -1;
3852 mHistoryOverflow = false;
3853 mActiveHistoryStates = 0xffffffff;
3854 mActiveHistoryStates2 = 0xffffffff;
3858 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptime,
3860 final boolean screenOff = !isScreenOn(screenState);
3861 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning();
3862 final boolean updateOnBatteryScreenOffTimeBase =
3863 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning();
3865 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) {
3866 if (updateOnBatteryScreenOffTimeBase) {
3867 updateKernelWakelocksLocked();
3868 updateBatteryPropertiesLocked();
3870 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because
3871 // updateRpmStatsLocked is too slow to run each screen change. When the speed is
3872 // improved, remove the surrounding if{}.
3873 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) {
3874 updateRpmStatsLocked(); // if either OnBattery or OnBatteryScreenOff timebase changes.
3876 if (DEBUG_ENERGY_CPU) {
3877 Slog.d(TAG, "Updating cpu time because screen is now "
3878 + Display.stateToString(screenState)
3879 + " and battery is " + (unplugged ? "on" : "off"));
3882 mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
3883 if (updateOnBatteryTimeBase) {
3884 for (int i = mUidStats.size() - 1; i >= 0; --i) {
3885 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime);
3888 if (updateOnBatteryScreenOffTimeBase) {
3889 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, uptime, realtime);
3890 for (int i = mUidStats.size() - 1; i >= 0; --i) {
3891 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime);
3897 private void updateBatteryPropertiesLocked() {
3899 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface(
3900 ServiceManager.getService("batteryproperties"));
3901 registrar.scheduleUpdate();
3902 } catch (RemoteException e) {
3907 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
3908 mIsolatedUids.put(isolatedUid, appUid);
3909 StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, appUid, isolatedUid,
3910 StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
3911 final Uid u = getUidStatsLocked(appUid);
3912 u.addIsolatedUid(isolatedUid);
3916 * Schedules a read of the latest cpu times before removing the isolated UID.
3917 * @see #removeIsolatedUidLocked(int)
3919 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) {
3920 int curUid = mIsolatedUids.get(isolatedUid, -1);
3921 if (curUid == appUid) {
3922 if (mExternalSync != null) {
3923 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid);
3929 * This should only be called after the cpu times have been read.
3930 * @see #scheduleRemoveIsolatedUidLocked(int, int)
3933 public void removeIsolatedUidLocked(int isolatedUid) {
3935 StatsLog.ISOLATED_UID_CHANGED, mIsolatedUids.get(isolatedUid, -1),
3936 isolatedUid, StatsLog.ISOLATED_UID_CHANGED__EVENT__REMOVED);
3937 final int idx = mIsolatedUids.indexOfKey(isolatedUid);
3939 final int ownerUid = mIsolatedUids.valueAt(idx);
3940 final Uid u = getUidStatsLocked(ownerUid);
3941 u.removeIsolatedUid(isolatedUid);
3942 mIsolatedUids.removeAt(idx);
3944 mKernelUidCpuTimeReader.removeUid(isolatedUid);
3945 mKernelUidCpuFreqTimeReader.removeUid(isolatedUid);
3946 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
3947 mKernelUidCpuActiveTimeReader.removeUid(isolatedUid);
3948 mKernelUidCpuClusterTimeReader.removeUid(isolatedUid);
3952 public int mapUid(int uid) {
3953 int isolated = mIsolatedUids.get(uid, -1);
3954 return isolated > 0 ? isolated : uid;
3957 public void noteEventLocked(int code, String name, int uid) {
3959 if (!mActiveEvents.updateState(code, name, uid, 0)) {
3962 final long elapsedRealtime = mClocks.elapsedRealtime();
3963 final long uptime = mClocks.uptimeMillis();
3964 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
3967 boolean ensureStartClockTime(final long currentTime) {
3968 final long ABOUT_ONE_YEAR = 365*24*60*60*1000L;
3969 if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) {
3970 // If the start clock time has changed by more than a year, then presumably
3971 // the previous time was completely bogus. So we are going to figure out a
3972 // new time based on how much time has elapsed since we started counting.
3973 mStartClockTime = currentTime - (mClocks.elapsedRealtime()-(mRealtimeStart/1000));
3979 public void noteCurrentTimeChangedLocked() {
3980 final long currentTime = System.currentTimeMillis();
3981 final long elapsedRealtime = mClocks.elapsedRealtime();
3982 final long uptime = mClocks.uptimeMillis();
3983 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
3984 ensureStartClockTime(currentTime);
3987 public void noteProcessStartLocked(String name, int uid) {
3989 if (isOnBattery()) {
3990 Uid u = getUidStatsLocked(uid);
3991 u.getProcessStatsLocked(name).incStartsLocked();
3993 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) {
3996 if (!mRecordAllHistory) {
3999 final long elapsedRealtime = mClocks.elapsedRealtime();
4000 final long uptime = mClocks.uptimeMillis();
4001 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid);
4004 public void noteProcessCrashLocked(String name, int uid) {
4006 if (isOnBattery()) {
4007 Uid u = getUidStatsLocked(uid);
4008 u.getProcessStatsLocked(name).incNumCrashesLocked();
4012 public void noteProcessAnrLocked(String name, int uid) {
4014 if (isOnBattery()) {
4015 Uid u = getUidStatsLocked(uid);
4016 u.getProcessStatsLocked(name).incNumAnrsLocked();
4020 public void noteUidProcessStateLocked(int uid, int state) {
4021 int parentUid = mapUid(uid);
4022 if (uid != parentUid) {
4023 // Isolated UIDs process state is already rolled up into parent, so no need to track
4024 // Otherwise the parent's process state will get downgraded incorrectly
4027 getUidStatsLocked(uid).updateUidProcessStateLocked(state);
4030 public void noteProcessFinishLocked(String name, int uid) {
4032 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) {
4035 if (!mRecordAllHistory) {
4038 final long elapsedRealtime = mClocks.elapsedRealtime();
4039 final long uptime = mClocks.uptimeMillis();
4040 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid);
4043 public void noteSyncStartLocked(String name, int uid) {
4045 final long elapsedRealtime = mClocks.elapsedRealtime();
4046 final long uptime = mClocks.uptimeMillis();
4047 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime);
4048 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
4051 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid);
4054 public void noteSyncFinishLocked(String name, int uid) {
4056 final long elapsedRealtime = mClocks.elapsedRealtime();
4057 final long uptime = mClocks.uptimeMillis();
4058 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime);
4059 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
4062 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid);
4065 public void noteJobStartLocked(String name, int uid) {
4067 final long elapsedRealtime = mClocks.elapsedRealtime();
4068 final long uptime = mClocks.uptimeMillis();
4069 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime);
4070 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
4073 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid);
4076 public void noteJobFinishLocked(String name, int uid, int stopReason) {
4078 final long elapsedRealtime = mClocks.elapsedRealtime();
4079 final long uptime = mClocks.uptimeMillis();
4080 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime, stopReason);
4081 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
4084 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid);
4087 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) {
4089 getUidStatsLocked(uid).noteJobsDeferredLocked(numDeferred, sinceLast);
4092 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) {
4093 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid);
4096 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) {
4097 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid);
4100 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource,
4102 if (!mRecordAllHistory) {
4106 final long elapsedRealtime = mClocks.elapsedRealtime();
4107 final long uptime = mClocks.uptimeMillis();
4109 if (workSource != null) {
4110 for (int i = 0; i < workSource.size(); ++i) {
4111 uid = mapUid(workSource.get(i));
4112 if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
4113 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid);
4117 List<WorkChain> workChains = workSource.getWorkChains();
4118 if (workChains != null) {
4119 for (int i = 0; i < workChains.size(); ++i) {
4120 uid = mapUid(workChains.get(i).getAttributionUid());
4121 if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
4122 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid);
4129 if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
4130 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid);
4135 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource,
4137 if (workSource != null) {
4138 for (int i = 0; i < workSource.size(); ++i) {
4139 uid = workSource.get(i);
4140 final String workSourceName = workSource.getName(i);
4142 if (isOnBattery()) {
4143 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid,
4144 workSourceName != null ? workSourceName : packageName);
4145 pkg.noteWakeupAlarmLocked(tag);
4147 StatsLog.write_non_chained(StatsLog.WAKEUP_ALARM_OCCURRED, workSource.get(i),
4148 workSource.getName(i), tag);
4151 ArrayList<WorkChain> workChains = workSource.getWorkChains();
4152 if (workChains != null) {
4153 for (int i = 0; i < workChains.size(); ++i) {
4154 final WorkChain wc = workChains.get(i);
4155 uid = wc.getAttributionUid();
4157 if (isOnBattery()) {
4158 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName);
4159 pkg.noteWakeupAlarmLocked(tag);
4161 StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, wc.getUids(), wc.getTags(), tag);
4165 if (isOnBattery()) {
4166 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName);
4167 pkg.noteWakeupAlarmLocked(tag);
4169 StatsLog.write_non_chained(StatsLog.WAKEUP_ALARM_OCCURRED, uid, null, tag);
4173 private void requestWakelockCpuUpdate() {
4174 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS);
4177 private void requestImmediateCpuUpdate() {
4178 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */);
4181 public void setRecordAllHistoryLocked(boolean enabled) {
4182 mRecordAllHistory = enabled;
4184 // Clear out any existing state.
4185 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK);
4186 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM);
4187 // Record the currently running processes as stopping, now that we are no
4188 // longer tracking them.
4189 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
4190 HistoryItem.EVENT_PROC);
4191 if (active != null) {
4192 long mSecRealtime = mClocks.elapsedRealtime();
4193 final long mSecUptime = mClocks.uptimeMillis();
4194 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
4195 SparseIntArray uids = ent.getValue();
4196 for (int j=0; j<uids.size(); j++) {
4197 addHistoryEventLocked(mSecRealtime, mSecUptime,
4198 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j));
4203 // Record the currently running processes as starting, now that we are tracking them.
4204 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
4205 HistoryItem.EVENT_PROC);
4206 if (active != null) {
4207 long mSecRealtime = mClocks.elapsedRealtime();
4208 final long mSecUptime = mClocks.uptimeMillis();
4209 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
4210 SparseIntArray uids = ent.getValue();
4211 for (int j=0; j<uids.size(); j++) {
4212 addHistoryEventLocked(mSecRealtime, mSecUptime,
4213 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j));
4220 public void setNoAutoReset(boolean enabled) {
4221 mNoAutoReset = enabled;
4224 public void setPretendScreenOff(boolean pretendScreenOff) {
4225 if (mPretendScreenOff != pretendScreenOff) {
4226 mPretendScreenOff = pretendScreenOff;
4227 noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON);
4231 private String mInitialAcquireWakeName;
4232 private int mInitialAcquireWakeUid = -1;
4234 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName,
4235 int type, boolean unimportantForLogging, long elapsedRealtime, long uptime) {
4237 if (type == WAKE_TYPE_PARTIAL) {
4238 // Only care about partial wake locks, since full wake locks
4239 // will be canceled when the user puts the screen to sleep.
4240 aggregateLastWakeupUptimeLocked(uptime);
4241 if (historyName == null) {
4244 if (mRecordAllHistory) {
4245 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
4247 addHistoryEventLocked(elapsedRealtime, uptime,
4248 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid);
4251 if (mWakeLockNesting == 0) {
4252 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
4253 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
4254 + Integer.toHexString(mHistoryCur.states));
4255 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
4256 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
4257 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
4258 mWakeLockImportant = !unimportantForLogging;
4259 addHistoryRecordLocked(elapsedRealtime, uptime);
4260 } else if (!mWakeLockImportant && !unimportantForLogging
4261 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
4262 if (mHistoryLastWritten.wakelockTag != null) {
4263 // We'll try to update the last tag.
4264 mHistoryLastWritten.wakelockTag = null;
4265 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
4266 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
4267 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
4268 addHistoryRecordLocked(elapsedRealtime, uptime);
4270 mWakeLockImportant = true;
4275 if (mOnBatteryScreenOffTimeBase.isRunning()) {
4276 // We only update the cpu time when a wake lock is acquired if the screen is off.
4277 // If the screen is on, we don't distribute the power amongst partial wakelocks.
4278 if (DEBUG_ENERGY_CPU) {
4279 Slog.d(TAG, "Updating cpu time because of +wake_lock");
4281 requestWakelockCpuUpdate();
4284 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
4287 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(),
4288 getPowerManagerWakeLockLevel(type), name,
4289 StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE);
4291 StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null,
4292 getPowerManagerWakeLockLevel(type), name,
4293 StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE);
4298 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName,
4299 int type, long elapsedRealtime, long uptime) {
4301 if (type == WAKE_TYPE_PARTIAL) {
4303 if (mRecordAllHistory) {
4304 if (historyName == null) {
4307 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
4309 addHistoryEventLocked(elapsedRealtime, uptime,
4310 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid);
4313 if (mWakeLockNesting == 0) {
4314 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
4315 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
4316 + Integer.toHexString(mHistoryCur.states));
4317 mInitialAcquireWakeName = null;
4318 mInitialAcquireWakeUid = -1;
4319 addHistoryRecordLocked(elapsedRealtime, uptime);
4323 if (mOnBatteryScreenOffTimeBase.isRunning()) {
4324 if (DEBUG_ENERGY_CPU) {
4325 Slog.d(TAG, "Updating cpu time because of -wake_lock");
4327 requestWakelockCpuUpdate();
4330 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
4332 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(),
4333 getPowerManagerWakeLockLevel(type), name,
4334 StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE);
4336 StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null,
4337 getPowerManagerWakeLockLevel(type), name,
4338 StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE);
4344 * Converts BatteryStats wakelock types back into PowerManager wakelock levels.
4345 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType().
4346 * These are estimations, since batterystats loses some of the original data.
4347 * TODO: Delete this. Instead, StatsLog.write should be called from PowerManager's Notifier.
4349 private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) {
4350 switch (battertStatsWakelockType) {
4351 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK
4352 case BatteryStats.WAKE_TYPE_PARTIAL:
4353 return PowerManager.PARTIAL_WAKE_LOCK;
4355 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK
4356 case BatteryStats.WAKE_TYPE_FULL:
4357 return PowerManager.FULL_WAKE_LOCK;
4359 case BatteryStats.WAKE_TYPE_DRAW:
4360 return PowerManager.DRAW_WAKE_LOCK;
4362 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent.
4363 case BatteryStats.WAKE_TYPE_WINDOW:
4364 Slog.e(TAG, "Illegal window wakelock type observed in batterystats.");
4368 Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType);
4373 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
4374 String historyName, int type, boolean unimportantForLogging) {
4375 final long elapsedRealtime = mClocks.elapsedRealtime();
4376 final long uptime = mClocks.uptimeMillis();
4377 final int N = ws.size();
4378 for (int i=0; i<N; i++) {
4379 noteStartWakeLocked(ws.get(i), pid, null, name, historyName, type,
4380 unimportantForLogging, elapsedRealtime, uptime);
4383 List<WorkChain> wcs = ws.getWorkChains();
4385 for (int i = 0; i < wcs.size(); ++i) {
4386 final WorkChain wc = wcs.get(i);
4387 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type,
4388 unimportantForLogging, elapsedRealtime, uptime);
4393 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
4394 String historyName, int type, WorkSource newWs, int newPid, String newName,
4395 String newHistoryName, int newType, boolean newUnimportantForLogging) {
4396 final long elapsedRealtime = mClocks.elapsedRealtime();
4397 final long uptime = mClocks.uptimeMillis();
4399 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs);
4401 // For correct semantics, we start the need worksources first, so that we won't
4402 // make inappropriate history items as if all wake locks went away and new ones
4403 // appeared. This is okay because tracking of wake locks allows nesting.
4405 // First the starts :
4406 final int NN = newWs.size();
4407 for (int i=0; i<NN; i++) {
4408 noteStartWakeLocked(newWs.get(i), newPid, null, newName, newHistoryName, newType,
4409 newUnimportantForLogging, elapsedRealtime, uptime);
4412 List<WorkChain> newChains = wcs[0];
4413 if (newChains != null) {
4414 for (int i = 0; i < newChains.size(); ++i) {
4415 final WorkChain newChain = newChains.get(i);
4416 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName,
4417 newHistoryName, newType, newUnimportantForLogging, elapsedRealtime,
4424 final int NO = ws.size();
4425 for (int i=0; i<NO; i++) {
4426 noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime,
4430 List<WorkChain> goneChains = wcs[1];
4431 if (goneChains != null) {
4432 for (int i = 0; i < goneChains.size(); ++i) {
4433 final WorkChain goneChain = goneChains.get(i);
4434 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name,
4435 historyName, type, elapsedRealtime, uptime);
4441 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
4442 String historyName, int type) {
4443 final long elapsedRealtime = mClocks.elapsedRealtime();
4444 final long uptime = mClocks.uptimeMillis();
4445 final int N = ws.size();
4446 for (int i=0; i<N; i++) {
4447 noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime,
4451 List<WorkChain> wcs = ws.getWorkChains();
4453 for (int i = 0; i < wcs.size(); ++i) {
4454 final WorkChain wc = wcs.get(i);
4455 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type,
4456 elapsedRealtime, uptime);
4461 public void noteLongPartialWakelockStart(String name, String historyName, int uid) {
4462 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
4463 uid, null, name, historyName,
4464 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
4467 noteLongPartialWakeLockStartInternal(name, historyName, uid);
4470 public void noteLongPartialWakelockStartFromSource(String name, String historyName,
4471 WorkSource workSource) {
4472 final int N = workSource.size();
4473 for (int i = 0; i < N; ++i) {
4474 final int uid = mapUid(workSource.get(i));
4475 noteLongPartialWakeLockStartInternal(name, historyName, uid);
4476 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
4477 workSource.get(i), workSource.getName(i), name, historyName,
4478 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
4481 final ArrayList<WorkChain> workChains = workSource.getWorkChains();
4482 if (workChains != null) {
4483 for (int i = 0; i < workChains.size(); ++i) {
4484 final WorkChain workChain = workChains.get(i);
4485 final int uid = workChain.getAttributionUid();
4486 noteLongPartialWakeLockStartInternal(name, historyName, uid);
4488 StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
4489 workChain.getUids(), workChain.getTags(), name, historyName,
4490 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
4495 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid) {
4496 final long elapsedRealtime = mClocks.elapsedRealtime();
4497 final long uptime = mClocks.uptimeMillis();
4498 if (historyName == null) {
4501 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid,
4505 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
4509 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) {
4510 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, uid, null,
4511 name, historyName, StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
4514 noteLongPartialWakeLockFinishInternal(name, historyName, uid);
4517 public void noteLongPartialWakelockFinishFromSource(String name, String historyName,
4518 WorkSource workSource) {
4519 final int N = workSource.size();
4520 for (int i = 0; i < N; ++i) {
4521 final int uid = mapUid(workSource.get(i));
4522 noteLongPartialWakeLockFinishInternal(name, historyName, uid);
4523 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
4524 workSource.get(i), workSource.getName(i), name, historyName,
4525 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
4528 final ArrayList<WorkChain> workChains = workSource.getWorkChains();
4529 if (workChains != null) {
4530 for (int i = 0; i < workChains.size(); ++i) {
4531 final WorkChain workChain = workChains.get(i);
4532 final int uid = workChain.getAttributionUid();
4533 noteLongPartialWakeLockFinishInternal(name, historyName, uid);
4534 StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
4535 workChain.getUids(), workChain.getTags(), name, historyName,
4536 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
4541 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid) {
4542 final long elapsedRealtime = mClocks.elapsedRealtime();
4543 final long uptime = mClocks.uptimeMillis();
4544 if (historyName == null) {
4547 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid,
4551 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
4555 void aggregateLastWakeupUptimeLocked(long uptimeMs) {
4556 if (mLastWakeupReason != null) {
4557 long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
4558 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
4559 timer.add(deltaUptime * 1000, 1); // time in in microseconds
4560 StatsLog.write(StatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason,
4561 /* duration_usec */ deltaUptime * 1000);
4562 mLastWakeupReason = null;
4566 public void noteWakeupReasonLocked(String reason) {
4567 final long elapsedRealtime = mClocks.elapsedRealtime();
4568 final long uptime = mClocks.uptimeMillis();
4569 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": "
4570 + Integer.toHexString(mHistoryCur.states));
4571 aggregateLastWakeupUptimeLocked(uptime);
4572 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
4573 mHistoryCur.wakeReasonTag.string = reason;
4574 mHistoryCur.wakeReasonTag.uid = 0;
4575 mLastWakeupReason = reason;
4576 mLastWakeupUptimeMs = uptime;
4577 addHistoryRecordLocked(elapsedRealtime, uptime);
4580 public boolean startAddingCpuLocked() {
4581 mExternalSync.cancelCpuSyncDueToWakelockChange();
4582 return mOnBatteryInternal;
4585 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime,
4586 int statSystemTime, int statIOWaitTime, int statIrqTime,
4587 int statSoftIrqTime, int statIdleTime) {
4588 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
4589 + " user=" + statUserTime + " sys=" + statSystemTime
4590 + " io=" + statIOWaitTime + " irq=" + statIrqTime
4591 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime);
4592 mCurStepCpuUserTime += totalUTime;
4593 mCurStepCpuSystemTime += totalSTime;
4594 mCurStepStatUserTime += statUserTime;
4595 mCurStepStatSystemTime += statSystemTime;
4596 mCurStepStatIOWaitTime += statIOWaitTime;
4597 mCurStepStatIrqTime += statIrqTime;
4598 mCurStepStatSoftIrqTime += statSoftIrqTime;
4599 mCurStepStatIdleTime += statIdleTime;
4602 public void noteProcessDiedLocked(int uid, int pid) {
4604 Uid u = mUidStats.get(uid);
4606 u.mPids.remove(pid);
4610 public long getProcessWakeTime(int uid, int pid, long realtime) {
4612 Uid u = mUidStats.get(uid);
4614 Uid.Pid p = u.mPids.get(pid);
4616 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
4622 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
4624 Uid u = mUidStats.get(uid);
4626 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
4632 public void noteStartSensorLocked(int uid, int sensor) {
4634 final long elapsedRealtime = mClocks.elapsedRealtime();
4635 final long uptime = mClocks.uptimeMillis();
4636 if (mSensorNesting == 0) {
4637 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
4638 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
4639 + Integer.toHexString(mHistoryCur.states));
4640 addHistoryRecordLocked(elapsedRealtime, uptime);
4643 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
4646 public void noteStopSensorLocked(int uid, int sensor) {
4648 final long elapsedRealtime = mClocks.elapsedRealtime();
4649 final long uptime = mClocks.uptimeMillis();
4651 if (mSensorNesting == 0) {
4652 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
4653 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
4654 + Integer.toHexString(mHistoryCur.states));
4655 addHistoryRecordLocked(elapsedRealtime, uptime);
4657 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
4662 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) {
4663 for (int i = 0; i < newWs.size(); ++i) {
4664 noteStartGpsLocked(newWs.get(i), null);
4667 for (int i = 0; i < oldWs.size(); ++i) {
4668 noteStopGpsLocked((oldWs.get(i)), null);
4671 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs);
4673 if (wcs[0] != null) {
4674 final List<WorkChain> newChains = wcs[0];
4675 for (int i = 0; i < newChains.size(); ++i) {
4676 noteStartGpsLocked(-1, newChains.get(i));
4680 if (wcs[1] != null) {
4681 final List<WorkChain> goneChains = wcs[1];
4682 for (int i = 0; i < goneChains.size(); ++i) {
4683 noteStopGpsLocked(-1, goneChains.get(i));
4689 private void noteStartGpsLocked(int uid, WorkChain workChain) {
4690 uid = getAttributionUid(uid, workChain);
4691 final long elapsedRealtime = mClocks.elapsedRealtime();
4692 final long uptime = mClocks.uptimeMillis();
4693 if (mGpsNesting == 0) {
4694 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
4695 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
4696 + Integer.toHexString(mHistoryCur.states));
4697 addHistoryRecordLocked(elapsedRealtime, uptime);
4701 if (workChain == null) {
4702 StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null,
4703 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON);
4705 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED,
4706 workChain.getUids(), workChain.getTags(),
4707 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON);
4710 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
4713 private void noteStopGpsLocked(int uid, WorkChain workChain) {
4714 uid = getAttributionUid(uid, workChain);
4715 final long elapsedRealtime = mClocks.elapsedRealtime();
4716 final long uptime = mClocks.uptimeMillis();
4718 if (mGpsNesting == 0) {
4719 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
4720 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
4721 + Integer.toHexString(mHistoryCur.states));
4722 addHistoryRecordLocked(elapsedRealtime, uptime);
4723 stopAllGpsSignalQualityTimersLocked(-1);
4724 mGpsSignalQualityBin = -1;
4727 if (workChain == null) {
4728 StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null,
4729 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF);
4731 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(),
4732 workChain.getTags(), StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF);
4735 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
4738 public void noteGpsSignalQualityLocked(int signalLevel) {
4739 if (mGpsNesting == 0) {
4742 if (signalLevel < 0 || signalLevel >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) {
4743 stopAllGpsSignalQualityTimersLocked(-1);
4746 final long elapsedRealtime = mClocks.elapsedRealtime();
4747 final long uptime = mClocks.uptimeMillis();
4748 if (mGpsSignalQualityBin != signalLevel) {
4749 if (mGpsSignalQualityBin >= 0) {
4750 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtime);
4752 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) {
4753 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtime);
4755 mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK)
4756 | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT);
4757 addHistoryRecordLocked(elapsedRealtime, uptime);
4758 mGpsSignalQualityBin = signalLevel;
4764 public void noteScreenStateLocked(int state) {
4765 state = mPretendScreenOff ? Display.STATE_OFF : state;
4767 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the
4768 // original 4 are mapped to one of the originals.
4769 if (state > MAX_TRACKED_SCREEN_STATE) {
4771 case Display.STATE_VR:
4772 state = Display.STATE_ON;
4775 Slog.wtf(TAG, "Unknown screen state (not mapped): " + state);
4780 if (mScreenState != state) {
4781 recordDailyStatsIfNeededLocked(true);
4782 final int oldState = mScreenState;
4783 mScreenState = state;
4784 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
4785 + ", newState=" + Display.stateToString(state));
4787 if (state != Display.STATE_UNKNOWN) {
4788 int stepState = state-1;
4789 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) {
4790 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState;
4791 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState;
4793 Slog.wtf(TAG, "Unexpected screen state: " + state);
4797 final long elapsedRealtime = mClocks.elapsedRealtime();
4798 final long uptime = mClocks.uptimeMillis();
4800 boolean updateHistory = false;
4801 if (isScreenDoze(state)) {
4802 mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG;
4803 mScreenDozeTimer.startRunningLocked(elapsedRealtime);
4804 updateHistory = true;
4805 } else if (isScreenDoze(oldState)) {
4806 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG;
4807 mScreenDozeTimer.stopRunningLocked(elapsedRealtime);
4808 updateHistory = true;
4810 if (isScreenOn(state)) {
4811 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
4812 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
4813 + Integer.toHexString(mHistoryCur.states));
4814 mScreenOnTimer.startRunningLocked(elapsedRealtime);
4815 if (mScreenBrightnessBin >= 0) {
4816 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
4818 updateHistory = true;
4819 } else if (isScreenOn(oldState)) {
4820 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
4821 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
4822 + Integer.toHexString(mHistoryCur.states));
4823 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
4824 if (mScreenBrightnessBin >= 0) {
4825 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
4827 updateHistory = true;
4829 if (updateHistory) {
4830 if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: "
4831 + Display.stateToString(state));
4832 addHistoryRecordLocked(elapsedRealtime, uptime);
4834 mExternalSync.scheduleCpuSyncDueToScreenStateChange(
4835 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning());
4836 if (isScreenOn(state)) {
4837 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state,
4838 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000);
4839 // Fake a wake lock, so we consider the device waked as long as the screen is on.
4840 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false,
4841 elapsedRealtime, uptime);
4842 } else if (isScreenOn(oldState)) {
4843 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL,
4844 elapsedRealtime, uptime);
4845 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state,
4846 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000);
4848 // Update discharge amounts.
4849 if (mOnBatteryInternal) {
4850 updateDischargeScreenLevelsLocked(oldState, state);
4855 public void noteScreenBrightnessLocked(int brightness) {
4856 // Bin the brightness.
4857 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
4858 if (bin < 0) bin = 0;
4859 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
4860 if (mScreenBrightnessBin != bin) {
4861 final long elapsedRealtime = mClocks.elapsedRealtime();
4862 final long uptime = mClocks.uptimeMillis();
4863 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
4864 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
4865 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
4866 + Integer.toHexString(mHistoryCur.states));
4867 addHistoryRecordLocked(elapsedRealtime, uptime);
4868 if (mScreenState == Display.STATE_ON) {
4869 if (mScreenBrightnessBin >= 0) {
4870 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
4872 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
4874 mScreenBrightnessBin = bin;
4878 public void noteUserActivityLocked(int uid, int event) {
4879 if (mOnBatteryInternal) {
4881 getUidStatsLocked(uid).noteUserActivityLocked(event);
4885 public void noteWakeUpLocked(String reason, int reasonUid) {
4886 final long elapsedRealtime = mClocks.elapsedRealtime();
4887 final long uptime = mClocks.uptimeMillis();
4888 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP,
4892 public void noteInteractiveLocked(boolean interactive) {
4893 if (mInteractive != interactive) {
4894 final long elapsedRealtime = mClocks.elapsedRealtime();
4895 mInteractive = interactive;
4896 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
4898 mInteractiveTimer.startRunningLocked(elapsedRealtime);
4900 mInteractiveTimer.stopRunningLocked(elapsedRealtime);
4905 public void noteConnectivityChangedLocked(int type, String extra) {
4906 final long elapsedRealtime = mClocks.elapsedRealtime();
4907 final long uptime = mClocks.uptimeMillis();
4908 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
4910 mNumConnectivityChange++;
4913 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis,
4914 final long uptimeMillis, int uid) {
4916 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
4918 getUidStatsLocked(uid).noteMobileRadioApWakeupLocked();
4922 * Updates the radio power state and returns true if an external stats collection should occur.
4924 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) {
4925 final long elapsedRealtime = mClocks.elapsedRealtime();
4926 final long uptime = mClocks.uptimeMillis();
4927 if (mMobileRadioPowerState != powerState) {
4928 long realElapsedRealtimeMs;
4929 final boolean active =
4930 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
4931 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
4934 noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid);
4937 mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000);
4938 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
4940 realElapsedRealtimeMs = timestampNs / (1000*1000);
4941 long lastUpdateTimeMs = mMobileRadioActiveStartTime;
4942 if (realElapsedRealtimeMs < lastUpdateTimeMs) {
4943 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
4944 + " is before start time " + lastUpdateTimeMs);
4945 realElapsedRealtimeMs = elapsedRealtime;
4946 } else if (realElapsedRealtimeMs < elapsedRealtime) {
4947 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
4948 - realElapsedRealtimeMs);
4950 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
4952 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
4953 + Integer.toHexString(mHistoryCur.states));
4954 addHistoryRecordLocked(elapsedRealtime, uptime);
4955 mMobileRadioPowerState = powerState;
4956 StatsLog.write(StatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, powerState);
4958 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
4959 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
4961 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
4962 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
4963 // Tell the caller to collect radio network/power stats.
4970 public void notePowerSaveModeLocked(boolean enabled) {
4971 if (mPowerSaveModeEnabled != enabled) {
4972 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0;
4973 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState;
4974 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
4975 final long elapsedRealtime = mClocks.elapsedRealtime();
4976 final long uptime = mClocks.uptimeMillis();
4977 mPowerSaveModeEnabled = enabled;
4979 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
4980 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
4981 + Integer.toHexString(mHistoryCur.states2));
4982 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime);
4984 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
4985 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
4986 + Integer.toHexString(mHistoryCur.states2));
4987 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime);
4989 addHistoryRecordLocked(elapsedRealtime, uptime);
4990 StatsLog.write(StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, enabled ?
4991 StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON :
4992 StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF);
4996 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) {
4997 final long elapsedRealtime = mClocks.elapsedRealtime();
4998 final long uptime = mClocks.uptimeMillis();
4999 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP;
5000 if (mDeviceIdling && !nowIdling && activeReason == null) {
5001 // We don't go out of general idling mode until explicitly taken out of
5002 // device idle through going active or significant motion.
5005 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT;
5006 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) {
5007 // We don't go out of general light idling mode until explicitly taken out of
5008 // device idle through going active or significant motion.
5009 nowLightIdling = true;
5011 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) {
5012 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
5013 activeReason, activeUid);
5015 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) {
5017 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP;
5018 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT;
5019 else statsmode = DEVICE_IDLE_MODE_OFF;
5020 StatsLog.write(StatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, statsmode);
5022 if (mDeviceIdling != nowIdling) {
5023 mDeviceIdling = nowIdling;
5024 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0;
5025 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState;
5026 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState;
5028 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime);
5030 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime);
5033 if (mDeviceLightIdling != nowLightIdling) {
5034 mDeviceLightIdling = nowLightIdling;
5035 if (nowLightIdling) {
5036 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime);
5038 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime);
5041 if (mDeviceIdleMode != mode) {
5042 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK)
5043 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT);
5044 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: "
5045 + Integer.toHexString(mHistoryCur.states2));
5046 addHistoryRecordLocked(elapsedRealtime, uptime);
5047 long lastDuration = elapsedRealtime - mLastIdleTimeStart;
5048 mLastIdleTimeStart = elapsedRealtime;
5049 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) {
5050 if (lastDuration > mLongestLightIdleTime) {
5051 mLongestLightIdleTime = lastDuration;
5053 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime);
5054 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) {
5055 if (lastDuration > mLongestFullIdleTime) {
5056 mLongestFullIdleTime = lastDuration;
5058 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime);
5060 if (mode == DEVICE_IDLE_MODE_LIGHT) {
5061 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime);
5062 } else if (mode == DEVICE_IDLE_MODE_DEEP) {
5063 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime);
5065 mDeviceIdleMode = mode;
5066 StatsLog.write(StatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode);
5070 public void notePackageInstalledLocked(String pkgName, long versionCode) {
5071 final long elapsedRealtime = mClocks.elapsedRealtime();
5072 final long uptime = mClocks.uptimeMillis();
5073 // XXX need to figure out what to do with long version codes.
5074 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED,
5075 pkgName, (int)versionCode);
5076 PackageChange pc = new PackageChange();
5077 pc.mPackageName = pkgName;
5079 pc.mVersionCode = versionCode;
5080 addPackageChange(pc);
5083 public void notePackageUninstalledLocked(String pkgName) {
5084 final long elapsedRealtime = mClocks.elapsedRealtime();
5085 final long uptime = mClocks.uptimeMillis();
5086 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
5088 PackageChange pc = new PackageChange();
5089 pc.mPackageName = pkgName;
5091 addPackageChange(pc);
5094 private void addPackageChange(PackageChange pc) {
5095 if (mDailyPackageChanges == null) {
5096 mDailyPackageChanges = new ArrayList<>();
5098 mDailyPackageChanges.add(pc);
5101 void stopAllGpsSignalQualityTimersLocked(int except) {
5102 final long elapsedRealtime = mClocks.elapsedRealtime();
5103 for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
5107 while (mGpsSignalQualityTimer[i].isRunningLocked()) {
5108 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtime);
5113 public void notePhoneOnLocked() {
5115 final long elapsedRealtime = mClocks.elapsedRealtime();
5116 final long uptime = mClocks.uptimeMillis();
5117 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
5118 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
5119 + Integer.toHexString(mHistoryCur.states));
5120 addHistoryRecordLocked(elapsedRealtime, uptime);
5122 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
5126 public void notePhoneOffLocked() {
5128 final long elapsedRealtime = mClocks.elapsedRealtime();
5129 final long uptime = mClocks.uptimeMillis();
5130 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
5131 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
5132 + Integer.toHexString(mHistoryCur.states));
5133 addHistoryRecordLocked(elapsedRealtime, uptime);
5135 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
5139 void stopAllPhoneSignalStrengthTimersLocked(int except) {
5140 final long elapsedRealtime = mClocks.elapsedRealtime();
5141 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
5145 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
5146 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
5151 private int fixPhoneServiceState(int state, int signalBin) {
5152 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
5153 // In this case we will always be STATE_OUT_OF_SERVICE, so need
5154 // to infer that we are scanning from other data.
5155 if (state == ServiceState.STATE_OUT_OF_SERVICE
5156 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
5157 state = ServiceState.STATE_IN_SERVICE;
5164 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
5165 boolean scanning = false;
5166 boolean newHistory = false;
5168 mPhoneServiceStateRaw = state;
5169 mPhoneSimStateRaw = simState;
5170 mPhoneSignalStrengthBinRaw = strengthBin;
5172 final long elapsedRealtime = mClocks.elapsedRealtime();
5173 final long uptime = mClocks.uptimeMillis();
5175 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
5176 // In this case we will always be STATE_OUT_OF_SERVICE, so need
5177 // to infer that we are scanning from other data.
5178 if (state == ServiceState.STATE_OUT_OF_SERVICE
5179 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
5180 state = ServiceState.STATE_IN_SERVICE;
5184 // If the phone is powered off, stop all timers.
5185 if (state == ServiceState.STATE_POWER_OFF) {
5188 // If we are in service, make sure the correct signal string timer is running.
5189 } else if (state == ServiceState.STATE_IN_SERVICE) {
5190 // Bin will be changed below.
5192 // If we're out of service, we are in the lowest signal strength
5193 // bin and have the scanning bit set.
5194 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
5196 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
5197 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
5198 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
5200 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
5201 + Integer.toHexString(mHistoryCur.states));
5202 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
5207 // If we are no longer scanning, then stop the scanning timer.
5208 if (mPhoneSignalScanningTimer.isRunningLocked()) {
5209 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
5210 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
5211 + Integer.toHexString(mHistoryCur.states));
5213 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
5217 if (mPhoneServiceState != state) {
5218 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
5219 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
5220 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
5221 + Integer.toHexString(mHistoryCur.states));
5223 mPhoneServiceState = state;
5226 if (mPhoneSignalStrengthBin != strengthBin) {
5227 if (mPhoneSignalStrengthBin >= 0) {
5228 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
5231 if (strengthBin >= 0) {
5232 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
5233 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
5235 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
5236 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
5237 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
5238 + Integer.toHexString(mHistoryCur.states));
5240 StatsLog.write(StatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin);
5242 stopAllPhoneSignalStrengthTimersLocked(-1);
5244 mPhoneSignalStrengthBin = strengthBin;
5248 addHistoryRecordLocked(elapsedRealtime, uptime);
5253 * Telephony stack updates the phone state.
5254 * @param state phone state from ServiceState.getState()
5256 public void notePhoneStateLocked(int state, int simState) {
5257 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
5260 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
5261 // Bin the strength.
5262 int bin = signalStrength.getLevel();
5263 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
5266 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
5267 int bin = DATA_CONNECTION_NONE;
5270 case TelephonyManager.NETWORK_TYPE_EDGE:
5271 bin = DATA_CONNECTION_EDGE;
5273 case TelephonyManager.NETWORK_TYPE_GPRS:
5274 bin = DATA_CONNECTION_GPRS;
5276 case TelephonyManager.NETWORK_TYPE_UMTS:
5277 bin = DATA_CONNECTION_UMTS;
5279 case TelephonyManager.NETWORK_TYPE_CDMA:
5280 bin = DATA_CONNECTION_CDMA;
5282 case TelephonyManager.NETWORK_TYPE_EVDO_0:
5283 bin = DATA_CONNECTION_EVDO_0;
5285 case TelephonyManager.NETWORK_TYPE_EVDO_A:
5286 bin = DATA_CONNECTION_EVDO_A;
5288 case TelephonyManager.NETWORK_TYPE_1xRTT:
5289 bin = DATA_CONNECTION_1xRTT;
5291 case TelephonyManager.NETWORK_TYPE_HSDPA:
5292 bin = DATA_CONNECTION_HSDPA;
5294 case TelephonyManager.NETWORK_TYPE_HSUPA:
5295 bin = DATA_CONNECTION_HSUPA;
5297 case TelephonyManager.NETWORK_TYPE_HSPA:
5298 bin = DATA_CONNECTION_HSPA;
5300 case TelephonyManager.NETWORK_TYPE_IDEN:
5301 bin = DATA_CONNECTION_IDEN;
5303 case TelephonyManager.NETWORK_TYPE_EVDO_B:
5304 bin = DATA_CONNECTION_EVDO_B;
5306 case TelephonyManager.NETWORK_TYPE_LTE:
5307 bin = DATA_CONNECTION_LTE;
5309 case TelephonyManager.NETWORK_TYPE_EHRPD:
5310 bin = DATA_CONNECTION_EHRPD;
5312 case TelephonyManager.NETWORK_TYPE_HSPAP:
5313 bin = DATA_CONNECTION_HSPAP;
5315 case TelephonyManager.NETWORK_TYPE_GSM:
5316 bin = DATA_CONNECTION_GSM;
5318 case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
5319 bin = DATA_CONNECTION_TD_SCDMA;
5321 case TelephonyManager.NETWORK_TYPE_IWLAN:
5322 bin = DATA_CONNECTION_IWLAN;
5324 case TelephonyManager.NETWORK_TYPE_LTE_CA:
5325 bin = DATA_CONNECTION_LTE_CA;
5328 bin = DATA_CONNECTION_OTHER;
5332 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
5333 if (mPhoneDataConnectionType != bin) {
5334 final long elapsedRealtime = mClocks.elapsedRealtime();
5335 final long uptime = mClocks.uptimeMillis();
5336 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
5337 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
5338 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
5339 + Integer.toHexString(mHistoryCur.states));
5340 addHistoryRecordLocked(elapsedRealtime, uptime);
5341 if (mPhoneDataConnectionType >= 0) {
5342 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
5345 mPhoneDataConnectionType = bin;
5346 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
5350 public void noteWifiOnLocked() {
5352 final long elapsedRealtime = mClocks.elapsedRealtime();
5353 final long uptime = mClocks.uptimeMillis();
5354 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
5355 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
5356 + Integer.toHexString(mHistoryCur.states));
5357 addHistoryRecordLocked(elapsedRealtime, uptime);
5359 mWifiOnTimer.startRunningLocked(elapsedRealtime);
5360 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI);
5364 public void noteWifiOffLocked() {
5365 final long elapsedRealtime = mClocks.elapsedRealtime();
5366 final long uptime = mClocks.uptimeMillis();
5368 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
5369 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
5370 + Integer.toHexString(mHistoryCur.states));
5371 addHistoryRecordLocked(elapsedRealtime, uptime);
5373 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
5374 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI);
5378 public void noteAudioOnLocked(int uid) {
5380 final long elapsedRealtime = mClocks.elapsedRealtime();
5381 final long uptime = mClocks.uptimeMillis();
5382 if (mAudioOnNesting == 0) {
5383 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
5384 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
5385 + Integer.toHexString(mHistoryCur.states));
5386 addHistoryRecordLocked(elapsedRealtime, uptime);
5387 mAudioOnTimer.startRunningLocked(elapsedRealtime);
5390 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
5393 public void noteAudioOffLocked(int uid) {
5394 if (mAudioOnNesting == 0) {
5398 final long elapsedRealtime = mClocks.elapsedRealtime();
5399 final long uptime = mClocks.uptimeMillis();
5400 if (--mAudioOnNesting == 0) {
5401 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
5402 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
5403 + Integer.toHexString(mHistoryCur.states));
5404 addHistoryRecordLocked(elapsedRealtime, uptime);
5405 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
5407 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
5410 public void noteVideoOnLocked(int uid) {
5412 final long elapsedRealtime = mClocks.elapsedRealtime();
5413 final long uptime = mClocks.uptimeMillis();
5414 if (mVideoOnNesting == 0) {
5415 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
5416 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
5417 + Integer.toHexString(mHistoryCur.states));
5418 addHistoryRecordLocked(elapsedRealtime, uptime);
5419 mVideoOnTimer.startRunningLocked(elapsedRealtime);
5422 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
5425 public void noteVideoOffLocked(int uid) {
5426 if (mVideoOnNesting == 0) {
5430 final long elapsedRealtime = mClocks.elapsedRealtime();
5431 final long uptime = mClocks.uptimeMillis();
5432 if (--mVideoOnNesting == 0) {
5433 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
5434 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
5435 + Integer.toHexString(mHistoryCur.states));
5436 addHistoryRecordLocked(elapsedRealtime, uptime);
5437 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
5439 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
5442 public void noteResetAudioLocked() {
5443 if (mAudioOnNesting > 0) {
5444 final long elapsedRealtime = mClocks.elapsedRealtime();
5445 final long uptime = mClocks.uptimeMillis();
5446 mAudioOnNesting = 0;
5447 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
5448 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
5449 + Integer.toHexString(mHistoryCur.states));
5450 addHistoryRecordLocked(elapsedRealtime, uptime);
5451 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime);
5452 for (int i=0; i<mUidStats.size(); i++) {
5453 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
5454 uid.noteResetAudioLocked(elapsedRealtime);
5459 public void noteResetVideoLocked() {
5460 if (mVideoOnNesting > 0) {
5461 final long elapsedRealtime = mClocks.elapsedRealtime();
5462 final long uptime = mClocks.uptimeMillis();
5463 mAudioOnNesting = 0;
5464 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
5465 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
5466 + Integer.toHexString(mHistoryCur.states));
5467 addHistoryRecordLocked(elapsedRealtime, uptime);
5468 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime);
5469 for (int i=0; i<mUidStats.size(); i++) {
5470 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
5471 uid.noteResetVideoLocked(elapsedRealtime);
5476 public void noteActivityResumedLocked(int uid) {
5478 getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime());
5481 public void noteActivityPausedLocked(int uid) {
5483 getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime());
5486 public void noteVibratorOnLocked(int uid, long durationMillis) {
5488 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
5491 public void noteVibratorOffLocked(int uid) {
5493 getUidStatsLocked(uid).noteVibratorOffLocked();
5496 public void noteFlashlightOnLocked(int uid) {
5498 final long elapsedRealtime = mClocks.elapsedRealtime();
5499 final long uptime = mClocks.uptimeMillis();
5500 if (mFlashlightOnNesting++ == 0) {
5501 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
5502 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
5503 + Integer.toHexString(mHistoryCur.states2));
5504 addHistoryRecordLocked(elapsedRealtime, uptime);
5505 mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
5507 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime);
5510 public void noteFlashlightOffLocked(int uid) {
5511 if (mFlashlightOnNesting == 0) {
5515 final long elapsedRealtime = mClocks.elapsedRealtime();
5516 final long uptime = mClocks.uptimeMillis();
5517 if (--mFlashlightOnNesting == 0) {
5518 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
5519 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
5520 + Integer.toHexString(mHistoryCur.states2));
5521 addHistoryRecordLocked(elapsedRealtime, uptime);
5522 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
5524 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime);
5527 public void noteCameraOnLocked(int uid) {
5529 final long elapsedRealtime = mClocks.elapsedRealtime();
5530 final long uptime = mClocks.uptimeMillis();
5531 if (mCameraOnNesting++ == 0) {
5532 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG;
5533 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: "
5534 + Integer.toHexString(mHistoryCur.states2));
5535 addHistoryRecordLocked(elapsedRealtime, uptime);
5536 mCameraOnTimer.startRunningLocked(elapsedRealtime);
5538 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime);
5541 public void noteCameraOffLocked(int uid) {
5542 if (mCameraOnNesting == 0) {
5546 final long elapsedRealtime = mClocks.elapsedRealtime();
5547 final long uptime = mClocks.uptimeMillis();
5548 if (--mCameraOnNesting == 0) {
5549 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
5550 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
5551 + Integer.toHexString(mHistoryCur.states2));
5552 addHistoryRecordLocked(elapsedRealtime, uptime);
5553 mCameraOnTimer.stopRunningLocked(elapsedRealtime);
5555 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime);
5558 public void noteResetCameraLocked() {
5559 if (mCameraOnNesting > 0) {
5560 final long elapsedRealtime = mClocks.elapsedRealtime();
5561 final long uptime = mClocks.uptimeMillis();
5562 mCameraOnNesting = 0;
5563 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
5564 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
5565 + Integer.toHexString(mHistoryCur.states2));
5566 addHistoryRecordLocked(elapsedRealtime, uptime);
5567 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime);
5568 for (int i=0; i<mUidStats.size(); i++) {
5569 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
5570 uid.noteResetCameraLocked(elapsedRealtime);
5575 public void noteResetFlashlightLocked() {
5576 if (mFlashlightOnNesting > 0) {
5577 final long elapsedRealtime = mClocks.elapsedRealtime();
5578 final long uptime = mClocks.uptimeMillis();
5579 mFlashlightOnNesting = 0;
5580 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
5581 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
5582 + Integer.toHexString(mHistoryCur.states2));
5583 addHistoryRecordLocked(elapsedRealtime, uptime);
5584 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime);
5585 for (int i=0; i<mUidStats.size(); i++) {
5586 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
5587 uid.noteResetFlashlightLocked(elapsedRealtime);
5592 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid,
5593 boolean isUnoptimized) {
5594 uid = getAttributionUid(uid, workChain);
5595 final long elapsedRealtime = mClocks.elapsedRealtime();
5596 final long uptime = mClocks.uptimeMillis();
5597 if (mBluetoothScanNesting == 0) {
5598 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
5599 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: "
5600 + Integer.toHexString(mHistoryCur.states2));
5601 addHistoryRecordLocked(elapsedRealtime, uptime);
5602 mBluetoothScanTimer.startRunningLocked(elapsedRealtime);
5604 mBluetoothScanNesting++;
5606 if (workChain != null) {
5607 StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED,
5608 workChain.getUids(), workChain.getTags(),
5609 StatsLog.BLE_SCAN_STATE_CHANGED__STATE__ON);
5610 if (isUnoptimized) {
5611 StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED,
5612 workChain.getUids(), workChain.getTags(),
5613 StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__ON);
5616 StatsLog.write_non_chained(StatsLog.BLE_SCAN_STATE_CHANGED, uid, null,
5617 StatsLog.BLE_SCAN_STATE_CHANGED__STATE__ON);
5618 if (isUnoptimized) {
5619 StatsLog.write_non_chained(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, uid, null,
5620 StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__ON);
5624 getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized);
5625 if (workChain != null) {
5626 getUidStatsLocked(uid).addBluetoothWorkChain(workChain, isUnoptimized);
5630 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
5631 final int N = ws.size();
5632 for (int i = 0; i < N; i++) {
5633 noteBluetoothScanStartedLocked(null, ws.get(i), isUnoptimized);
5636 final List<WorkChain> workChains = ws.getWorkChains();
5637 if (workChains != null) {
5638 for (int i = 0; i < workChains.size(); ++i) {
5639 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized);
5644 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid,
5645 boolean isUnoptimized) {
5646 uid = getAttributionUid(uid, workChain);
5647 final long elapsedRealtime = mClocks.elapsedRealtime();
5648 final long uptime = mClocks.uptimeMillis();
5649 mBluetoothScanNesting--;
5650 if (mBluetoothScanNesting == 0) {
5651 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
5652 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: "
5653 + Integer.toHexString(mHistoryCur.states2));
5654 addHistoryRecordLocked(elapsedRealtime, uptime);
5655 mBluetoothScanTimer.stopRunningLocked(elapsedRealtime);
5658 if (workChain != null) {
5660 StatsLog.BLE_SCAN_STATE_CHANGED, workChain.getUids(), workChain.getTags(),
5661 StatsLog.BLE_SCAN_STATE_CHANGED__STATE__OFF);
5662 if (isUnoptimized) {
5663 StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED,
5664 workChain.getUids(), workChain.getTags(),
5665 StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__OFF);
5668 StatsLog.write_non_chained(StatsLog.BLE_SCAN_STATE_CHANGED, uid, null,
5669 StatsLog.BLE_SCAN_STATE_CHANGED__STATE__OFF);
5670 if (isUnoptimized) {
5671 StatsLog.write_non_chained(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, uid, null,
5672 StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__OFF);
5676 getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized);
5677 if (workChain != null) {
5678 getUidStatsLocked(uid).removeBluetoothWorkChain(workChain, isUnoptimized);
5682 private int getAttributionUid(int uid, WorkChain workChain) {
5683 if (workChain != null) {
5684 return mapUid(workChain.getAttributionUid());
5690 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
5691 final int N = ws.size();
5692 for (int i = 0; i < N; i++) {
5693 noteBluetoothScanStoppedLocked(null, ws.get(i), isUnoptimized);
5696 final List<WorkChain> workChains = ws.getWorkChains();
5697 if (workChains != null) {
5698 for (int i = 0; i < workChains.size(); ++i) {
5699 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized);
5704 public void noteResetBluetoothScanLocked() {
5705 if (mBluetoothScanNesting > 0) {
5706 final long elapsedRealtime = mClocks.elapsedRealtime();
5707 final long uptime = mClocks.uptimeMillis();
5708 mBluetoothScanNesting = 0;
5709 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
5710 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: "
5711 + Integer.toHexString(mHistoryCur.states2));
5712 addHistoryRecordLocked(elapsedRealtime, uptime);
5713 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime);
5716 for (int i=0; i<mUidStats.size(); i++) {
5717 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
5718 uid.noteResetBluetoothScanLocked(elapsedRealtime);
5720 List<WorkChain> allWorkChains = uid.getAllBluetoothWorkChains();
5721 if (allWorkChains != null) {
5722 for (int j = 0; j < allWorkChains.size(); ++j) {
5723 StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED,
5724 allWorkChains.get(j).getUids(),
5725 allWorkChains.get(j).getTags(),
5726 StatsLog.BLE_SCAN_STATE_CHANGED__STATE__OFF);
5728 allWorkChains.clear();
5731 List<WorkChain> unoptimizedWorkChains = uid.getUnoptimizedBluetoothWorkChains();
5732 if (unoptimizedWorkChains != null) {
5733 for (int j = 0; j < unoptimizedWorkChains.size(); ++j) {
5734 StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED,
5735 unoptimizedWorkChains.get(j).getUids(),
5736 unoptimizedWorkChains.get(j).getTags(),
5737 StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__OFF);
5739 unoptimizedWorkChains.clear();
5745 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) {
5746 final int N = ws.size();
5747 for (int i = 0; i < N; i++) {
5748 int uid = mapUid(ws.get(i));
5749 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults);
5750 StatsLog.write_non_chained(StatsLog.BLE_SCAN_RESULT_RECEIVED, ws.get(i), ws.getName(i),
5754 final List<WorkChain> workChains = ws.getWorkChains();
5755 if (workChains != null) {
5756 for (int i = 0; i < workChains.size(); ++i) {
5757 final WorkChain wc = workChains.get(i);
5758 int uid = mapUid(wc.getAttributionUid());
5759 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults);
5760 StatsLog.write(StatsLog.BLE_SCAN_RESULT_RECEIVED,
5761 wc.getUids(), wc.getTags(), numNewResults);
5766 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis,
5767 final long uptimeMillis, int uid) {
5769 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
5771 getUidStatsLocked(uid).noteWifiRadioApWakeupLocked();
5774 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) {
5775 final long elapsedRealtime = mClocks.elapsedRealtime();
5776 final long uptime = mClocks.uptimeMillis();
5777 if (mWifiRadioPowerState != powerState) {
5778 final boolean active =
5779 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
5780 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
5783 noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid);
5785 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
5786 mWifiActiveTimer.startRunningLocked(elapsedRealtime);
5788 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
5789 mWifiActiveTimer.stopRunningLocked(
5790 timestampNs / (1000 * 1000));
5792 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: "
5793 + Integer.toHexString(mHistoryCur.states));
5794 addHistoryRecordLocked(elapsedRealtime, uptime);
5795 mWifiRadioPowerState = powerState;
5796 StatsLog.write(StatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, powerState);
5800 public void noteWifiRunningLocked(WorkSource ws) {
5801 if (!mGlobalWifiRunning) {
5802 final long elapsedRealtime = mClocks.elapsedRealtime();
5803 final long uptime = mClocks.uptimeMillis();
5804 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
5805 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
5806 + Integer.toHexString(mHistoryCur.states));
5807 addHistoryRecordLocked(elapsedRealtime, uptime);
5808 mGlobalWifiRunning = true;
5809 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
5811 for (int i=0; i<N; i++) {
5812 int uid = mapUid(ws.get(i));
5813 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
5816 List<WorkChain> workChains = ws.getWorkChains();
5817 if (workChains != null) {
5818 for (int i = 0; i < workChains.size(); ++i) {
5819 int uid = mapUid(workChains.get(i).getAttributionUid());
5820 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
5824 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI);
5826 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
5830 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
5831 if (mGlobalWifiRunning) {
5832 final long elapsedRealtime = mClocks.elapsedRealtime();
5833 int N = oldWs.size();
5834 for (int i=0; i<N; i++) {
5835 int uid = mapUid(oldWs.get(i));
5836 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
5839 List<WorkChain> workChains = oldWs.getWorkChains();
5840 if (workChains != null) {
5841 for (int i = 0; i < workChains.size(); ++i) {
5842 int uid = mapUid(workChains.get(i).getAttributionUid());
5843 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
5848 for (int i=0; i<N; i++) {
5849 int uid = mapUid(newWs.get(i));
5850 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
5853 workChains = newWs.getWorkChains();
5854 if (workChains != null) {
5855 for (int i = 0; i < workChains.size(); ++i) {
5856 int uid = mapUid(workChains.get(i).getAttributionUid());
5857 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
5861 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
5865 public void noteWifiStoppedLocked(WorkSource ws) {
5866 if (mGlobalWifiRunning) {
5867 final long elapsedRealtime = mClocks.elapsedRealtime();
5868 final long uptime = mClocks.uptimeMillis();
5869 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
5870 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
5871 + Integer.toHexString(mHistoryCur.states));
5872 addHistoryRecordLocked(elapsedRealtime, uptime);
5873 mGlobalWifiRunning = false;
5874 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
5876 for (int i=0; i<N; i++) {
5877 int uid = mapUid(ws.get(i));
5878 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
5881 List<WorkChain> workChains = ws.getWorkChains();
5882 if (workChains != null) {
5883 for (int i = 0; i < workChains.size(); ++i) {
5884 int uid = mapUid(workChains.get(i).getAttributionUid());
5885 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
5889 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI);
5891 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
5895 public void noteWifiStateLocked(int wifiState, String accessPoint) {
5896 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
5897 if (mWifiState != wifiState) {
5898 final long elapsedRealtime = mClocks.elapsedRealtime();
5899 if (mWifiState >= 0) {
5900 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
5902 mWifiState = wifiState;
5903 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
5904 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI);
5908 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
5909 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
5910 if (mWifiSupplState != supplState) {
5911 final long elapsedRealtime = mClocks.elapsedRealtime();
5912 final long uptime = mClocks.uptimeMillis();
5913 if (mWifiSupplState >= 0) {
5914 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime);
5916 mWifiSupplState = supplState;
5917 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime);
5918 mHistoryCur.states2 =
5919 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
5920 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
5921 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
5922 + Integer.toHexString(mHistoryCur.states2));
5923 addHistoryRecordLocked(elapsedRealtime, uptime);
5927 void stopAllWifiSignalStrengthTimersLocked(int except) {
5928 final long elapsedRealtime = mClocks.elapsedRealtime();
5929 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
5933 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) {
5934 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
5939 public void noteWifiRssiChangedLocked(int newRssi) {
5940 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
5941 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
5942 if (mWifiSignalStrengthBin != strengthBin) {
5943 final long elapsedRealtime = mClocks.elapsedRealtime();
5944 final long uptime = mClocks.uptimeMillis();
5945 if (mWifiSignalStrengthBin >= 0) {
5946 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked(
5949 if (strengthBin >= 0) {
5950 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
5951 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
5952 StatsLog.write(StatsLog.WIFI_SIGNAL_STRENGTH_CHANGED, strengthBin);
5954 mHistoryCur.states2 =
5955 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
5956 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
5957 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
5958 + Integer.toHexString(mHistoryCur.states2));
5959 addHistoryRecordLocked(elapsedRealtime, uptime);
5961 stopAllWifiSignalStrengthTimersLocked(-1);
5963 mWifiSignalStrengthBin = strengthBin;
5967 int mWifiFullLockNesting = 0;
5969 public void noteFullWifiLockAcquiredLocked(int uid) {
5970 final long elapsedRealtime = mClocks.elapsedRealtime();
5971 final long uptime = mClocks.uptimeMillis();
5972 if (mWifiFullLockNesting == 0) {
5973 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
5974 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
5975 + Integer.toHexString(mHistoryCur.states));
5976 addHistoryRecordLocked(elapsedRealtime, uptime);
5978 mWifiFullLockNesting++;
5979 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
5982 public void noteFullWifiLockReleasedLocked(int uid) {
5983 final long elapsedRealtime = mClocks.elapsedRealtime();
5984 final long uptime = mClocks.uptimeMillis();
5985 mWifiFullLockNesting--;
5986 if (mWifiFullLockNesting == 0) {
5987 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
5988 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
5989 + Integer.toHexString(mHistoryCur.states));
5990 addHistoryRecordLocked(elapsedRealtime, uptime);
5992 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
5995 int mWifiScanNesting = 0;
5997 public void noteWifiScanStartedLocked(int uid) {
5998 final long elapsedRealtime = mClocks.elapsedRealtime();
5999 final long uptime = mClocks.uptimeMillis();
6000 if (mWifiScanNesting == 0) {
6001 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
6002 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
6003 + Integer.toHexString(mHistoryCur.states));
6004 addHistoryRecordLocked(elapsedRealtime, uptime);
6007 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
6010 public void noteWifiScanStoppedLocked(int uid) {
6011 final long elapsedRealtime = mClocks.elapsedRealtime();
6012 final long uptime = mClocks.uptimeMillis();
6014 if (mWifiScanNesting == 0) {
6015 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
6016 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
6017 + Integer.toHexString(mHistoryCur.states));
6018 addHistoryRecordLocked(elapsedRealtime, uptime);
6020 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
6023 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
6025 final long elapsedRealtime = mClocks.elapsedRealtime();
6026 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
6029 public void noteWifiBatchedScanStoppedLocked(int uid) {
6031 final long elapsedRealtime = mClocks.elapsedRealtime();
6032 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
6035 int mWifiMulticastNesting = 0;
6037 public void noteWifiMulticastEnabledLocked(int uid) {
6039 final long elapsedRealtime = mClocks.elapsedRealtime();
6040 final long uptime = mClocks.uptimeMillis();
6041 if (mWifiMulticastNesting == 0) {
6042 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
6043 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
6044 + Integer.toHexString(mHistoryCur.states));
6045 addHistoryRecordLocked(elapsedRealtime, uptime);
6047 // Start Wifi Multicast overall timer
6048 if (!mWifiMulticastWakelockTimer.isRunningLocked()) {
6049 if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started");
6050 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtime);
6053 mWifiMulticastNesting++;
6054 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
6057 public void noteWifiMulticastDisabledLocked(int uid) {
6059 final long elapsedRealtime = mClocks.elapsedRealtime();
6060 final long uptime = mClocks.uptimeMillis();
6061 mWifiMulticastNesting--;
6062 if (mWifiMulticastNesting == 0) {
6063 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
6064 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
6065 + Integer.toHexString(mHistoryCur.states));
6066 addHistoryRecordLocked(elapsedRealtime, uptime);
6068 // Stop Wifi Multicast overall timer
6069 if (mWifiMulticastWakelockTimer.isRunningLocked()) {
6070 if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped");
6071 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtime);
6074 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
6077 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
6079 for (int i=0; i<N; i++) {
6080 final int uid = mapUid(ws.get(i));
6081 noteFullWifiLockAcquiredLocked(uid);
6082 StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i),
6083 StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON);
6086 final List<WorkChain> workChains = ws.getWorkChains();
6087 if (workChains != null) {
6088 for (int i = 0; i < workChains.size(); ++i) {
6089 final WorkChain workChain = workChains.get(i);
6090 final int uid = mapUid(workChain.getAttributionUid());
6091 noteFullWifiLockAcquiredLocked(uid);
6092 StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED,
6093 workChain.getUids(), workChain.getTags(),
6094 StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON);
6099 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
6101 for (int i=0; i<N; i++) {
6102 final int uid = mapUid(ws.get(i));
6103 noteFullWifiLockReleasedLocked(uid);
6104 StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i),
6105 StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF);
6108 final List<WorkChain> workChains = ws.getWorkChains();
6109 if (workChains != null) {
6110 for (int i = 0; i < workChains.size(); ++i) {
6111 final WorkChain workChain = workChains.get(i);
6112 final int uid = mapUid(workChain.getAttributionUid());
6113 noteFullWifiLockReleasedLocked(uid);
6114 StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED,
6115 workChain.getUids(), workChain.getTags(),
6116 StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF);
6121 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
6123 for (int i=0; i<N; i++) {
6124 final int uid = mapUid(ws.get(i));
6125 noteWifiScanStartedLocked(uid);
6126 StatsLog.write_non_chained(StatsLog.WIFI_SCAN_STATE_CHANGED, ws.get(i), ws.getName(i),
6127 StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__ON);
6130 final List<WorkChain> workChains = ws.getWorkChains();
6131 if (workChains != null) {
6132 for (int i = 0; i < workChains.size(); ++i) {
6133 final WorkChain workChain = workChains.get(i);
6134 final int uid = mapUid(workChain.getAttributionUid());
6135 noteWifiScanStartedLocked(uid);
6136 StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED, workChain.getUids(),
6137 workChain.getTags(), StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__ON);
6142 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
6144 for (int i=0; i<N; i++) {
6145 final int uid = mapUid(ws.get(i));
6146 noteWifiScanStoppedLocked(uid);
6147 StatsLog.write_non_chained(StatsLog.WIFI_SCAN_STATE_CHANGED, ws.get(i), ws.getName(i),
6148 StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__OFF);
6151 final List<WorkChain> workChains = ws.getWorkChains();
6152 if (workChains != null) {
6153 for (int i = 0; i < workChains.size(); ++i) {
6154 final WorkChain workChain = workChains.get(i);
6155 final int uid = mapUid(workChain.getAttributionUid());
6156 noteWifiScanStoppedLocked(uid);
6157 StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED,
6158 workChain.getUids(), workChain.getTags(),
6159 StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__OFF);
6164 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
6166 for (int i=0; i<N; i++) {
6167 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
6170 final List<WorkChain> workChains = ws.getWorkChains();
6171 if (workChains != null) {
6172 for (int i = 0; i < workChains.size(); ++i) {
6173 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph);
6178 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
6180 for (int i=0; i<N; i++) {
6181 noteWifiBatchedScanStoppedLocked(ws.get(i));
6184 final List<WorkChain> workChains = ws.getWorkChains();
6185 if (workChains != null) {
6186 for (int i = 0; i < workChains.size(); ++i) {
6187 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid());
6192 private static String[] includeInStringArray(String[] array, String str) {
6193 if (ArrayUtils.indexOf(array, str) >= 0) {
6196 String[] newArray = new String[array.length+1];
6197 System.arraycopy(array, 0, newArray, 0, array.length);
6198 newArray[array.length] = str;
6202 private static String[] excludeFromStringArray(String[] array, String str) {
6203 int index = ArrayUtils.indexOf(array, str);
6205 String[] newArray = new String[array.length-1];
6207 System.arraycopy(array, 0, newArray, 0, index);
6209 if (index < array.length-1) {
6210 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
6217 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
6218 if (TextUtils.isEmpty(iface)) return;
6220 synchronized (mModemNetworkLock) {
6221 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
6222 mModemIfaces = includeInStringArray(mModemIfaces, iface);
6223 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces);
6225 mModemIfaces = excludeFromStringArray(mModemIfaces, iface);
6226 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces);
6230 synchronized (mWifiNetworkLock) {
6231 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
6232 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
6233 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
6235 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
6236 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
6241 public String[] getWifiIfaces() {
6242 synchronized (mWifiNetworkLock) {
6247 public String[] getMobileIfaces() {
6248 synchronized (mModemNetworkLock) {
6249 return mModemIfaces;
6253 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
6254 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6257 @Override public int getScreenOnCount(int which) {
6258 return mScreenOnTimer.getCountLocked(which);
6261 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) {
6262 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6265 @Override public int getScreenDozeCount(int which) {
6266 return mScreenDozeTimer.getCountLocked(which);
6269 @Override public long getScreenBrightnessTime(int brightnessBin,
6270 long elapsedRealtimeUs, int which) {
6271 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
6272 elapsedRealtimeUs, which);
6275 @Override public Timer getScreenBrightnessTimer(int brightnessBin) {
6276 return mScreenBrightnessTimer[brightnessBin];
6279 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
6280 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6283 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) {
6284 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6287 @Override public int getPowerSaveModeEnabledCount(int which) {
6288 return mPowerSaveModeEnabledTimer.getCountLocked(which);
6291 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs,
6294 case DEVICE_IDLE_MODE_LIGHT:
6295 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6296 case DEVICE_IDLE_MODE_DEEP:
6297 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6302 @Override public int getDeviceIdleModeCount(int mode, int which) {
6304 case DEVICE_IDLE_MODE_LIGHT:
6305 return mDeviceIdleModeLightTimer.getCountLocked(which);
6306 case DEVICE_IDLE_MODE_DEEP:
6307 return mDeviceIdleModeFullTimer.getCountLocked(which);
6312 @Override public long getLongestDeviceIdleModeTime(int mode) {
6314 case DEVICE_IDLE_MODE_LIGHT:
6315 return mLongestLightIdleTime;
6316 case DEVICE_IDLE_MODE_DEEP:
6317 return mLongestFullIdleTime;
6322 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) {
6324 case DEVICE_IDLE_MODE_LIGHT:
6325 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6326 case DEVICE_IDLE_MODE_DEEP:
6327 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6332 @Override public int getDeviceIdlingCount(int mode, int which) {
6334 case DEVICE_IDLE_MODE_LIGHT:
6335 return mDeviceLightIdlingTimer.getCountLocked(which);
6336 case DEVICE_IDLE_MODE_DEEP:
6337 return mDeviceIdlingTimer.getCountLocked(which);
6342 @Override public int getNumConnectivityChange(int which) {
6343 int val = mNumConnectivityChange;
6344 if (which == STATS_CURRENT) {
6345 val -= mLoadedNumConnectivityChange;
6346 } else if (which == STATS_SINCE_UNPLUGGED) {
6347 val -= mUnpluggedNumConnectivityChange;
6352 @Override public long getGpsSignalQualityTime(int strengthBin,
6353 long elapsedRealtimeUs, int which) {
6354 if (strengthBin < 0 || strengthBin >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) {
6357 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked(
6358 elapsedRealtimeUs, which);
6361 @Override public long getGpsBatteryDrainMaMs() {
6362 final double opVolt = mPowerProfile.getAveragePower(
6363 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0;
6367 double energyUsedMaMs = 0.0;
6368 final int which = STATS_SINCE_CHARGED;
6369 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
6370 for(int i=0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
6372 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i)
6373 * (getGpsSignalQualityTime(i, rawRealtime, which) / 1000);
6375 return (long) energyUsedMaMs;
6378 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
6379 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6382 @Override public int getPhoneOnCount(int which) {
6383 return mPhoneOnTimer.getCountLocked(which);
6386 @Override public long getPhoneSignalStrengthTime(int strengthBin,
6387 long elapsedRealtimeUs, int which) {
6388 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
6389 elapsedRealtimeUs, which);
6392 @Override public long getPhoneSignalScanningTime(
6393 long elapsedRealtimeUs, int which) {
6394 return mPhoneSignalScanningTimer.getTotalTimeLocked(
6395 elapsedRealtimeUs, which);
6398 @Override public Timer getPhoneSignalScanningTimer() {
6399 return mPhoneSignalScanningTimer;
6402 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
6403 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
6406 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) {
6407 return mPhoneSignalStrengthsTimer[strengthBin];
6410 @Override public long getPhoneDataConnectionTime(int dataType,
6411 long elapsedRealtimeUs, int which) {
6412 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
6413 elapsedRealtimeUs, which);
6416 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
6417 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
6420 @Override public Timer getPhoneDataConnectionTimer(int dataType) {
6421 return mPhoneDataConnectionsTimer[dataType];
6424 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
6425 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6428 @Override public int getMobileRadioActiveCount(int which) {
6429 return mMobileRadioActiveTimer.getCountLocked(which);
6432 @Override public long getMobileRadioActiveAdjustedTime(int which) {
6433 return mMobileRadioActiveAdjustedTime.getCountLocked(which);
6436 @Override public long getMobileRadioActiveUnknownTime(int which) {
6437 return mMobileRadioActiveUnknownTime.getCountLocked(which);
6440 @Override public int getMobileRadioActiveUnknownCount(int which) {
6441 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
6444 @Override public long getWifiMulticastWakelockTime(
6445 long elapsedRealtimeUs, int which) {
6446 return mWifiMulticastWakelockTimer.getTotalTimeLocked(
6447 elapsedRealtimeUs, which);
6450 @Override public int getWifiMulticastWakelockCount(int which) {
6451 return mWifiMulticastWakelockTimer.getCountLocked(which);
6454 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
6455 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6458 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) {
6459 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6462 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
6463 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6466 @Override public long getWifiStateTime(int wifiState,
6467 long elapsedRealtimeUs, int which) {
6468 return mWifiStateTimer[wifiState].getTotalTimeLocked(
6469 elapsedRealtimeUs, which);
6472 @Override public int getWifiStateCount(int wifiState, int which) {
6473 return mWifiStateTimer[wifiState].getCountLocked(which);
6476 @Override public Timer getWifiStateTimer(int wifiState) {
6477 return mWifiStateTimer[wifiState];
6480 @Override public long getWifiSupplStateTime(int state,
6481 long elapsedRealtimeUs, int which) {
6482 return mWifiSupplStateTimer[state].getTotalTimeLocked(
6483 elapsedRealtimeUs, which);
6486 @Override public int getWifiSupplStateCount(int state, int which) {
6487 return mWifiSupplStateTimer[state].getCountLocked(which);
6490 @Override public Timer getWifiSupplStateTimer(int state) {
6491 return mWifiSupplStateTimer[state];
6494 @Override public long getWifiSignalStrengthTime(int strengthBin,
6495 long elapsedRealtimeUs, int which) {
6496 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
6497 elapsedRealtimeUs, which);
6500 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) {
6501 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which);
6504 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) {
6505 return mWifiSignalStrengthsTimer[strengthBin];
6509 public ControllerActivityCounter getBluetoothControllerActivity() {
6510 return mBluetoothActivity;
6514 public ControllerActivityCounter getWifiControllerActivity() {
6515 return mWifiActivity;
6519 public ControllerActivityCounter getModemControllerActivity() {
6520 return mModemActivity;
6524 public boolean hasBluetoothActivityReporting() {
6525 return mHasBluetoothReporting;
6529 public boolean hasWifiActivityReporting() {
6530 return mHasWifiReporting;
6534 public boolean hasModemActivityReporting() {
6535 return mHasModemReporting;
6539 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) {
6540 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6544 public long getFlashlightOnCount(int which) {
6545 return mFlashlightOnTimer.getCountLocked(which);
6549 public long getCameraOnTime(long elapsedRealtimeUs, int which) {
6550 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6554 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) {
6555 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
6559 public long getNetworkActivityBytes(int type, int which) {
6560 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
6561 return mNetworkByteActivityCounters[type].getCountLocked(which);
6568 public long getNetworkActivityPackets(int type, int which) {
6569 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
6570 return mNetworkPacketActivityCounters[type].getCountLocked(which);
6576 @Override public long getStartClockTime() {
6577 final long currentTime = System.currentTimeMillis();
6578 if (ensureStartClockTime(currentTime)) {
6579 recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(),
6580 mClocks.uptimeMillis());
6582 return mStartClockTime;
6585 @Override public String getStartPlatformVersion() {
6586 return mStartPlatformVersion;
6589 @Override public String getEndPlatformVersion() {
6590 return mEndPlatformVersion;
6593 @Override public int getParcelVersion() {
6597 @Override public boolean getIsOnBattery() {
6601 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
6605 private static void detachTimerIfNotNull(BatteryStatsImpl.Timer timer) {
6606 if (timer != null) {
6611 private static boolean resetTimerIfNotNull(BatteryStatsImpl.Timer timer,
6612 boolean detachIfReset) {
6613 if (timer != null) {
6614 return timer.reset(detachIfReset);
6619 private static boolean resetTimerIfNotNull(DualTimer timer, boolean detachIfReset) {
6620 if (timer != null) {
6621 return timer.reset(detachIfReset);
6626 private static void detachLongCounterIfNotNull(LongSamplingCounter counter) {
6627 if (counter != null) {
6632 private static void resetLongCounterIfNotNull(LongSamplingCounter counter,
6633 boolean detachIfReset) {
6634 if (counter != null) {
6635 counter.reset(detachIfReset);
6640 * The statistics associated with a particular uid.
6642 public static class Uid extends BatteryStats.Uid {
6644 * BatteryStatsImpl that we are associated with.
6646 protected BatteryStatsImpl mBsi;
6650 /** TimeBase for when uid is in background and device is on battery. */
6651 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
6652 public final TimeBase mOnBatteryBackgroundTimeBase;
6653 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
6654 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase;
6656 boolean mWifiRunning;
6657 StopwatchTimer mWifiRunningTimer;
6659 boolean mFullWifiLockOut;
6660 StopwatchTimer mFullWifiLockTimer;
6662 boolean mWifiScanStarted;
6663 DualTimer mWifiScanTimer;
6665 static final int NO_BATCHED_SCAN_STARTED = -1;
6666 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
6667 StopwatchTimer[] mWifiBatchedScanTimer;
6669 boolean mWifiMulticastEnabled;
6670 StopwatchTimer mWifiMulticastTimer;
6672 StopwatchTimer mAudioTurnedOnTimer;
6673 StopwatchTimer mVideoTurnedOnTimer;
6674 StopwatchTimer mFlashlightTurnedOnTimer;
6675 StopwatchTimer mCameraTurnedOnTimer;
6676 StopwatchTimer mForegroundActivityTimer;
6677 StopwatchTimer mForegroundServiceTimer;
6678 /** Total time spent by the uid holding any partial wakelocks. */
6679 DualTimer mAggregatedPartialWakelockTimer;
6680 DualTimer mBluetoothScanTimer;
6681 DualTimer mBluetoothUnoptimizedScanTimer;
6682 Counter mBluetoothScanResultCounter;
6683 Counter mBluetoothScanResultBgCounter;
6685 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
6686 StopwatchTimer[] mProcessStateTimer;
6688 boolean mInForegroundService = false;
6690 BatchTimer mVibratorOnTimer;
6692 Counter[] mUserActivityCounters;
6694 LongSamplingCounter[] mNetworkByteActivityCounters;
6695 LongSamplingCounter[] mNetworkPacketActivityCounters;
6696 LongSamplingCounter mMobileRadioActiveTime;
6697 LongSamplingCounter mMobileRadioActiveCount;
6700 * How many times this UID woke up the Application Processor due to a Mobile radio packet.
6702 private LongSamplingCounter mMobileRadioApWakeupCount;
6705 * How many times this UID woke up the Application Processor due to a Wifi packet.
6707 private LongSamplingCounter mWifiRadioApWakeupCount;
6710 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode.
6711 * Can be null if the UID has had no such activity.
6713 private ControllerActivityCounterImpl mWifiControllerActivity;
6716 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode.
6717 * Can be null if the UID has had no such activity.
6719 private ControllerActivityCounterImpl mBluetoothControllerActivity;
6722 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode.
6723 * Can be null if the UID has had no such activity.
6725 private ControllerActivityCounterImpl mModemControllerActivity;
6728 * The CPU times we had at the last history details update.
6730 long mLastStepUserTime;
6731 long mLastStepSystemTime;
6732 long mCurStepUserTime;
6733 long mCurStepSystemTime;
6735 LongSamplingCounter mUserCpuTime;
6736 LongSamplingCounter mSystemCpuTime;
6737 LongSamplingCounter[][] mCpuClusterSpeedTimesUs;
6738 LongSamplingCounter mCpuActiveTimeMs;
6740 LongSamplingCounterArray mCpuFreqTimeMs;
6741 LongSamplingCounterArray mScreenOffCpuFreqTimeMs;
6742 LongSamplingCounterArray mCpuClusterTimesMs;
6744 LongSamplingCounterArray[] mProcStateTimeMs;
6745 LongSamplingCounterArray[] mProcStateScreenOffTimeMs;
6747 IntArray mChildUids;
6750 * The statistics we have collected for this uid's wake locks.
6752 final OverflowArrayMap<Wakelock> mWakelockStats;
6755 * The statistics we have collected for this uid's syncs.
6757 final OverflowArrayMap<DualTimer> mSyncStats;
6760 * The statistics we have collected for this uid's jobs.
6762 final OverflowArrayMap<DualTimer> mJobStats;
6765 * Count of the jobs that have completed and the reasons why they completed.
6767 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>();
6770 * Count of app launch events that had associated deferred job counts or info about
6771 * last time a job was run.
6773 Counter mJobsDeferredEventCount;
6776 * Count of deferred jobs that were pending when the app was launched or brought to
6777 * the foreground through a user interaction.
6779 Counter mJobsDeferredCount;
6782 * Sum of time since the last time a job was run for this app before it was launched.
6784 LongSamplingCounter mJobsFreshnessTimeMs;
6787 * Array of counts of instances where the time since the last job was run for the app
6788 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}.
6790 final Counter[] mJobsFreshnessBuckets;
6793 * The statistics we have collected for this uid's sensor activations.
6795 final SparseArray<Sensor> mSensorStats = new SparseArray<>();
6798 * The statistics we have collected for this uid's processes.
6800 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>();
6803 * The statistics we have collected for this uid's processes.
6805 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>();
6808 * The transient wake stats we have collected for this uid's pids.
6810 final SparseArray<Pid> mPids = new SparseArray<>();
6813 * The list of WorkChains associated with active bluetooth scans.
6815 * NOTE: This is a hack and it only needs to exist because there's a "reset" API that is
6816 * supposed to stop and log all WorkChains that were currently active.
6818 ArrayList<WorkChain> mAllBluetoothChains = null;
6819 ArrayList<WorkChain> mUnoptimizedBluetoothChains = null;
6821 public Uid(BatteryStatsImpl bsi, int uid) {
6825 mOnBatteryBackgroundTimeBase = new TimeBase();
6826 mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
6827 mBsi.mClocks.elapsedRealtime() * 1000);
6829 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase();
6830 mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
6831 mBsi.mClocks.elapsedRealtime() * 1000);
6833 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6834 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6835 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6836 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase);
6838 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) {
6839 @Override public Wakelock instantiateObject() {
6840 return new Wakelock(mBsi, Uid.this);
6843 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) {
6844 @Override public DualTimer instantiateObject() {
6845 return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null,
6846 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
6849 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) {
6850 @Override public DualTimer instantiateObject() {
6851 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null,
6852 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
6856 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING,
6857 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase);
6858 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK,
6859 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase);
6860 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN,
6861 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
6862 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
6863 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED,
6864 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase);
6865 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
6866 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase);
6867 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase);
6868 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6869 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length];
6873 public void setProcessStateForTest(int procState) {
6874 mProcessState = procState;
6878 public long[] getCpuFreqTimes(int which) {
6879 return nullIfAllZeros(mCpuFreqTimeMs, which);
6883 public long[] getScreenOffCpuFreqTimes(int which) {
6884 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which);
6888 public long getCpuActiveTime() {
6889 return mCpuActiveTimeMs.getCountLocked(STATS_SINCE_CHARGED);
6893 public long[] getCpuClusterTimes() {
6894 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED);
6899 public long[] getCpuFreqTimes(int which, int procState) {
6900 if (which < 0 || which >= NUM_PROCESS_STATE) {
6903 if (mProcStateTimeMs == null) {
6906 if (!mBsi.mPerProcStateCpuTimesAvailable) {
6907 mProcStateTimeMs = null;
6910 return nullIfAllZeros(mProcStateTimeMs[procState], which);
6914 public long[] getScreenOffCpuFreqTimes(int which, int procState) {
6915 if (which < 0 || which >= NUM_PROCESS_STATE) {
6918 if (mProcStateScreenOffTimeMs == null) {
6921 if (!mBsi.mPerProcStateCpuTimesAvailable) {
6922 mProcStateScreenOffTimeMs = null;
6925 return nullIfAllZeros(mProcStateScreenOffTimeMs[procState], which);
6928 public void addIsolatedUid(int isolatedUid) {
6929 if (mChildUids == null) {
6930 mChildUids = new IntArray();
6931 } else if (mChildUids.indexOf(isolatedUid) >= 0) {
6934 mChildUids.add(isolatedUid);
6937 public void removeIsolatedUid(int isolatedUid) {
6938 final int idx = mChildUids == null ? -1 : mChildUids.indexOf(isolatedUid);
6942 mChildUids.remove(idx);
6945 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) {
6946 if (cpuTimesMs == null) {
6949 final long[] counts = cpuTimesMs.getCountsLocked(which);
6950 if (counts == null) {
6953 // Return counts only if at least one of the elements is non-zero.
6954 for (int i = counts.length - 1; i >= 0; --i) {
6955 if (counts[i] != 0) {
6962 private void addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery) {
6963 if (mProcStateTimeMs == null) {
6964 mProcStateTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE];
6966 if (mProcStateTimeMs[procState] == null
6967 || mProcStateTimeMs[procState].getSize() != cpuTimesMs.length) {
6968 mProcStateTimeMs[procState] = new LongSamplingCounterArray(
6969 mBsi.mOnBatteryTimeBase);
6971 mProcStateTimeMs[procState].addCountLocked(cpuTimesMs, onBattery);
6974 private void addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs,
6975 boolean onBatteryScreenOff) {
6976 if (mProcStateScreenOffTimeMs == null) {
6977 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE];
6979 if (mProcStateScreenOffTimeMs[procState] == null
6980 || mProcStateScreenOffTimeMs[procState].getSize() != cpuTimesMs.length) {
6981 mProcStateScreenOffTimeMs[procState] = new LongSamplingCounterArray(
6982 mBsi.mOnBatteryScreenOffTimeBase);
6984 mProcStateScreenOffTimeMs[procState].addCountLocked(cpuTimesMs, onBatteryScreenOff);
6988 public Timer getAggregatedPartialWakelockTimer() {
6989 return mAggregatedPartialWakelockTimer;
6993 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
6994 return mWakelockStats.getMap();
6998 public Timer getMulticastWakelockStats() {
6999 return mWifiMulticastTimer;
7003 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() {
7004 return mSyncStats.getMap();
7008 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() {
7009 return mJobStats.getMap();
7013 public ArrayMap<String, SparseIntArray> getJobCompletionStats() {
7014 return mJobCompletions;
7018 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() {
7019 return mSensorStats;
7023 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
7024 return mProcessStats;
7028 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
7029 return mPackageStats;
7033 public int getUid() {
7038 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
7039 if (!mWifiRunning) {
7040 mWifiRunning = true;
7041 if (mWifiRunningTimer == null) {
7042 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING,
7043 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase);
7045 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
7050 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
7052 mWifiRunning = false;
7053 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
7058 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
7059 if (!mFullWifiLockOut) {
7060 mFullWifiLockOut = true;
7061 if (mFullWifiLockTimer == null) {
7062 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK,
7063 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase);
7065 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
7070 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
7071 if (mFullWifiLockOut) {
7072 mFullWifiLockOut = false;
7073 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
7078 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
7079 if (!mWifiScanStarted) {
7080 mWifiScanStarted = true;
7081 if (mWifiScanTimer == null) {
7082 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN,
7083 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase,
7084 mOnBatteryBackgroundTimeBase);
7086 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
7091 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
7092 if (mWifiScanStarted) {
7093 mWifiScanStarted = false;
7094 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
7099 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
7101 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) {
7106 if (mWifiBatchedScanBinStarted == bin) return;
7108 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
7109 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
7110 stopRunningLocked(elapsedRealtimeMs);
7112 mWifiBatchedScanBinStarted = bin;
7113 if (mWifiBatchedScanTimer[bin] == null) {
7114 makeWifiBatchedScanBin(bin, null);
7116 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
7120 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
7121 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
7122 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
7123 stopRunningLocked(elapsedRealtimeMs);
7124 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
7129 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
7130 if (!mWifiMulticastEnabled) {
7131 mWifiMulticastEnabled = true;
7132 if (mWifiMulticastTimer == null) {
7133 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7134 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase);
7136 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
7137 StatsLog.write_non_chained(
7138 StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null,
7139 StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__ON);
7144 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
7145 if (mWifiMulticastEnabled) {
7146 mWifiMulticastEnabled = false;
7147 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
7148 StatsLog.write_non_chained(
7149 StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null,
7150 StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__OFF);
7155 public ControllerActivityCounter getWifiControllerActivity() {
7156 return mWifiControllerActivity;
7160 public ControllerActivityCounter getBluetoothControllerActivity() {
7161 return mBluetoothControllerActivity;
7165 public ControllerActivityCounter getModemControllerActivity() {
7166 return mModemControllerActivity;
7169 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() {
7170 if (mWifiControllerActivity == null) {
7171 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
7174 return mWifiControllerActivity;
7177 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() {
7178 if (mBluetoothControllerActivity == null) {
7179 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
7182 return mBluetoothControllerActivity;
7185 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() {
7186 if (mModemControllerActivity == null) {
7187 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
7188 ModemActivityInfo.TX_POWER_LEVELS);
7190 return mModemControllerActivity;
7193 public StopwatchTimer createAudioTurnedOnTimerLocked() {
7194 if (mAudioTurnedOnTimer == null) {
7195 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON,
7196 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase);
7198 return mAudioTurnedOnTimer;
7201 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
7202 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
7203 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null,
7204 StatsLog.AUDIO_STATE_CHANGED__STATE__ON);
7207 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
7208 if (mAudioTurnedOnTimer != null) {
7209 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
7210 if (!mAudioTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
7211 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null,
7212 StatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
7217 public void noteResetAudioLocked(long elapsedRealtimeMs) {
7218 if (mAudioTurnedOnTimer != null) {
7219 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
7220 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null,
7221 StatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
7225 public StopwatchTimer createVideoTurnedOnTimerLocked() {
7226 if (mVideoTurnedOnTimer == null) {
7227 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON,
7228 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase);
7230 return mVideoTurnedOnTimer;
7233 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
7234 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
7235 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), null,
7236 StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__ON);
7239 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
7240 if (mVideoTurnedOnTimer != null) {
7241 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
7242 if (!mVideoTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
7243 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(),
7244 null, StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__OFF);
7249 public void noteResetVideoLocked(long elapsedRealtimeMs) {
7250 if (mVideoTurnedOnTimer != null) {
7251 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
7252 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), null,
7253 StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__OFF);
7257 public StopwatchTimer createFlashlightTurnedOnTimerLocked() {
7258 if (mFlashlightTurnedOnTimer == null) {
7259 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7260 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase);
7262 return mFlashlightTurnedOnTimer;
7265 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) {
7266 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
7267 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,
7268 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON);
7271 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) {
7272 if (mFlashlightTurnedOnTimer != null) {
7273 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
7274 if (!mFlashlightTurnedOnTimer.isRunningLocked()) {
7275 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,
7276 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
7281 public void noteResetFlashlightLocked(long elapsedRealtimeMs) {
7282 if (mFlashlightTurnedOnTimer != null) {
7283 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
7284 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,
7285 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
7289 public StopwatchTimer createCameraTurnedOnTimerLocked() {
7290 if (mCameraTurnedOnTimer == null) {
7291 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON,
7292 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase);
7294 return mCameraTurnedOnTimer;
7297 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) {
7298 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
7299 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null,
7300 StatsLog.CAMERA_STATE_CHANGED__STATE__ON);
7303 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) {
7304 if (mCameraTurnedOnTimer != null) {
7305 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
7306 if (!mCameraTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
7307 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null,
7308 StatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
7313 public void noteResetCameraLocked(long elapsedRealtimeMs) {
7314 if (mCameraTurnedOnTimer != null) {
7315 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
7316 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null,
7317 StatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
7321 public StopwatchTimer createForegroundActivityTimerLocked() {
7322 if (mForegroundActivityTimer == null) {
7323 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7324 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase);
7326 return mForegroundActivityTimer;
7329 public StopwatchTimer createForegroundServiceTimerLocked() {
7330 if (mForegroundServiceTimer == null) {
7331 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7332 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase);
7334 return mForegroundServiceTimer;
7337 public DualTimer createAggregatedPartialWakelockTimerLocked() {
7338 if (mAggregatedPartialWakelockTimer == null) {
7339 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
7340 AGGREGATED_WAKE_TYPE_PARTIAL, null,
7341 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase);
7343 return mAggregatedPartialWakelockTimer;
7346 public DualTimer createBluetoothScanTimerLocked() {
7347 if (mBluetoothScanTimer == null) {
7348 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
7349 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
7350 mOnBatteryBackgroundTimeBase);
7352 return mBluetoothScanTimer;
7355 public DualTimer createBluetoothUnoptimizedScanTimerLocked() {
7356 if (mBluetoothUnoptimizedScanTimer == null) {
7357 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
7358 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
7359 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
7361 return mBluetoothUnoptimizedScanTimer;
7364 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs,
7365 boolean isUnoptimized) {
7366 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
7367 if (isUnoptimized) {
7368 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
7372 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
7373 if (mBluetoothScanTimer != null) {
7374 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
7376 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) {
7377 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs);
7381 public void addBluetoothWorkChain(WorkChain workChain, boolean isUnoptimized) {
7382 if (mAllBluetoothChains == null) {
7383 mAllBluetoothChains = new ArrayList<WorkChain>(4);
7386 if (isUnoptimized && mUnoptimizedBluetoothChains == null) {
7387 mUnoptimizedBluetoothChains = new ArrayList<WorkChain>(4);
7390 mAllBluetoothChains.add(workChain);
7391 if (isUnoptimized) {
7392 mUnoptimizedBluetoothChains.add(workChain);
7396 public void removeBluetoothWorkChain(WorkChain workChain, boolean isUnoptimized) {
7397 if (mAllBluetoothChains != null) {
7398 mAllBluetoothChains.remove(workChain);
7401 if (isUnoptimized && mUnoptimizedBluetoothChains != null) {
7402 mUnoptimizedBluetoothChains.remove(workChain);
7406 public List<WorkChain> getAllBluetoothWorkChains() {
7407 return mAllBluetoothChains;
7410 public List<WorkChain> getUnoptimizedBluetoothWorkChains() {
7411 return mUnoptimizedBluetoothChains;
7415 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) {
7416 if (mBluetoothScanTimer != null) {
7417 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
7419 if (mBluetoothUnoptimizedScanTimer != null) {
7420 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
7424 public Counter createBluetoothScanResultCounterLocked() {
7425 if (mBluetoothScanResultCounter == null) {
7426 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase);
7428 return mBluetoothScanResultCounter;
7431 public Counter createBluetoothScanResultBgCounterLocked() {
7432 if (mBluetoothScanResultBgCounter == null) {
7433 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase);
7435 return mBluetoothScanResultBgCounter;
7438 public void noteBluetoothScanResultsLocked(int numNewResults) {
7439 createBluetoothScanResultCounterLocked().addAtomic(numNewResults);
7440 // Uses background timebase, so the count will only be incremented if uid in background.
7441 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults);
7445 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
7446 // We always start, since we want multiple foreground PIDs to nest
7447 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
7451 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
7452 if (mForegroundActivityTimer != null) {
7453 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
7457 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) {
7458 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs);
7461 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) {
7462 if (mForegroundServiceTimer != null) {
7463 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs);
7467 public BatchTimer createVibratorOnTimerLocked() {
7468 if (mVibratorOnTimer == null) {
7469 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON,
7470 mBsi.mOnBatteryTimeBase);
7472 return mVibratorOnTimer;
7475 public void noteVibratorOnLocked(long durationMillis) {
7476 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis);
7479 public void noteVibratorOffLocked() {
7480 if (mVibratorOnTimer != null) {
7481 mVibratorOnTimer.abortLastDuration(mBsi);
7486 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
7487 if (mWifiRunningTimer == null) {
7490 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
7494 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
7495 if (mFullWifiLockTimer == null) {
7498 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
7502 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
7503 if (mWifiScanTimer == null) {
7506 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
7510 public int getWifiScanCount(int which) {
7511 if (mWifiScanTimer == null) {
7514 return mWifiScanTimer.getCountLocked(which);
7518 public Timer getWifiScanTimer() {
7519 return mWifiScanTimer;
7523 public int getWifiScanBackgroundCount(int which) {
7524 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) {
7527 return mWifiScanTimer.getSubTimer().getCountLocked(which);
7531 public long getWifiScanActualTime(final long elapsedRealtimeUs) {
7532 if (mWifiScanTimer == null) {
7535 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000;
7536 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000;
7540 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) {
7541 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) {
7544 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000;
7545 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000;
7549 public Timer getWifiScanBackgroundTimer() {
7550 if (mWifiScanTimer == null) {
7553 return mWifiScanTimer.getSubTimer();
7557 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
7558 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
7559 if (mWifiBatchedScanTimer[csphBin] == null) {
7562 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
7566 public int getWifiBatchedScanCount(int csphBin, int which) {
7567 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
7568 if (mWifiBatchedScanTimer[csphBin] == null) {
7571 return mWifiBatchedScanTimer[csphBin].getCountLocked(which);
7575 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
7576 if (mWifiMulticastTimer == null) {
7579 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
7583 public Timer getAudioTurnedOnTimer() {
7584 return mAudioTurnedOnTimer;
7588 public Timer getVideoTurnedOnTimer() {
7589 return mVideoTurnedOnTimer;
7593 public Timer getFlashlightTurnedOnTimer() {
7594 return mFlashlightTurnedOnTimer;
7598 public Timer getCameraTurnedOnTimer() {
7599 return mCameraTurnedOnTimer;
7603 public Timer getForegroundActivityTimer() {
7604 return mForegroundActivityTimer;
7608 public Timer getForegroundServiceTimer() {
7609 return mForegroundServiceTimer;
7613 public Timer getBluetoothScanTimer() {
7614 return mBluetoothScanTimer;
7618 public Timer getBluetoothScanBackgroundTimer() {
7619 if (mBluetoothScanTimer == null) {
7622 return mBluetoothScanTimer.getSubTimer();
7626 public Timer getBluetoothUnoptimizedScanTimer() {
7627 return mBluetoothUnoptimizedScanTimer;
7631 public Timer getBluetoothUnoptimizedScanBackgroundTimer() {
7632 if (mBluetoothUnoptimizedScanTimer == null) {
7635 return mBluetoothUnoptimizedScanTimer.getSubTimer();
7639 public Counter getBluetoothScanResultCounter() {
7640 return mBluetoothScanResultCounter;
7644 public Counter getBluetoothScanResultBgCounter() {
7645 return mBluetoothScanResultBgCounter;
7648 void makeProcessState(int i, Parcel in) {
7649 if (i < 0 || i >= NUM_PROCESS_STATE) return;
7652 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null,
7653 mBsi.mOnBatteryTimeBase);
7655 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null,
7656 mBsi.mOnBatteryTimeBase, in);
7661 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) {
7662 if (state < 0 || state >= NUM_PROCESS_STATE) return 0;
7663 if (mProcessStateTimer[state] == null) {
7666 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which);
7670 public Timer getProcessStateTimer(int state) {
7671 if (state < 0 || state >= NUM_PROCESS_STATE) return null;
7672 return mProcessStateTimer[state];
7676 public Timer getVibratorOnTimer() {
7677 return mVibratorOnTimer;
7681 public void noteUserActivityLocked(int type) {
7682 if (mUserActivityCounters == null) {
7683 initUserActivityLocked();
7685 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
7686 mUserActivityCounters[type].stepAtomic();
7688 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
7694 public boolean hasUserActivity() {
7695 return mUserActivityCounters != null;
7699 public int getUserActivityCount(int type, int which) {
7700 if (mUserActivityCounters == null) {
7703 return mUserActivityCounters[type].getCountLocked(which);
7706 void makeWifiBatchedScanBin(int i, Parcel in) {
7707 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
7709 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i);
7710 if (collected == null) {
7711 collected = new ArrayList<StopwatchTimer>();
7712 mBsi.mWifiBatchedScanTimers.put(i, collected);
7715 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN,
7716 collected, mBsi.mOnBatteryTimeBase);
7718 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN,
7719 collected, mBsi.mOnBatteryTimeBase, in);
7724 void initUserActivityLocked() {
7725 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
7726 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
7727 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase);
7731 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
7732 if (mNetworkByteActivityCounters == null) {
7733 initNetworkActivityLocked();
7735 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
7736 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
7737 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
7739 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
7744 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
7745 if (mNetworkByteActivityCounters == null) {
7746 initNetworkActivityLocked();
7748 mMobileRadioActiveTime.addCountLocked(batteryUptime);
7749 mMobileRadioActiveCount.addCountLocked(1);
7753 public boolean hasNetworkActivity() {
7754 return mNetworkByteActivityCounters != null;
7758 public long getNetworkActivityBytes(int type, int which) {
7759 if (mNetworkByteActivityCounters != null && type >= 0
7760 && type < mNetworkByteActivityCounters.length) {
7761 return mNetworkByteActivityCounters[type].getCountLocked(which);
7768 public long getNetworkActivityPackets(int type, int which) {
7769 if (mNetworkPacketActivityCounters != null && type >= 0
7770 && type < mNetworkPacketActivityCounters.length) {
7771 return mNetworkPacketActivityCounters[type].getCountLocked(which);
7778 public long getMobileRadioActiveTime(int which) {
7779 return mMobileRadioActiveTime != null
7780 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
7784 public int getMobileRadioActiveCount(int which) {
7785 return mMobileRadioActiveCount != null
7786 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
7790 public long getUserCpuTimeUs(int which) {
7791 return mUserCpuTime.getCountLocked(which);
7795 public long getSystemCpuTimeUs(int which) {
7796 return mSystemCpuTime.getCountLocked(which);
7800 public long getTimeAtCpuSpeed(int cluster, int step, int which) {
7801 if (mCpuClusterSpeedTimesUs != null) {
7802 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) {
7803 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster];
7804 if (cpuSpeedTimesUs != null) {
7805 if (step >= 0 && step < cpuSpeedTimesUs.length) {
7806 final LongSamplingCounter c = cpuSpeedTimesUs[step];
7808 return c.getCountLocked(which);
7817 public void noteMobileRadioApWakeupLocked() {
7818 if (mMobileRadioApWakeupCount == null) {
7819 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
7821 mMobileRadioApWakeupCount.addCountLocked(1);
7825 public long getMobileRadioApWakeupCount(int which) {
7826 if (mMobileRadioApWakeupCount != null) {
7827 return mMobileRadioApWakeupCount.getCountLocked(which);
7832 public void noteWifiRadioApWakeupLocked() {
7833 if (mWifiRadioApWakeupCount == null) {
7834 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
7836 mWifiRadioApWakeupCount.addCountLocked(1);
7840 public long getWifiRadioApWakeupCount(int which) {
7841 if (mWifiRadioApWakeupCount != null) {
7842 return mWifiRadioApWakeupCount.getCountLocked(which);
7848 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) {
7850 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which);
7851 if (deferredEventCount == 0) {
7854 final int deferredCount = mJobsDeferredCount.getCountLocked(which);
7855 final long averageLatency = deferredEventCount != 0
7856 ? mJobsFreshnessTimeMs.getCountLocked(which) / deferredEventCount
7858 sb.append(deferredEventCount); sb.append(',');
7859 sb.append(deferredCount); sb.append(',');
7860 sb.append(averageLatency);
7861 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
7862 if (mJobsFreshnessBuckets[i] == null) {
7866 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which));
7872 public void getDeferredJobsLineLocked(StringBuilder sb, int which) {
7874 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which);
7875 if (deferredEventCount == 0) {
7878 final int deferredCount = mJobsDeferredCount.getCountLocked(which);
7879 final long averageLatency = deferredEventCount != 0
7880 ? mJobsFreshnessTimeMs.getCountLocked(which) / deferredEventCount
7882 sb.append("times="); sb.append(deferredEventCount); sb.append(", ");
7883 sb.append("count="); sb.append(deferredCount); sb.append(", ");
7884 sb.append("avgLatency="); sb.append(averageLatency); sb.append(", ");
7885 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
7886 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms=");
7887 if (mJobsFreshnessBuckets[i] == null) {
7890 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which));
7896 void initNetworkActivityLocked() {
7897 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
7898 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
7899 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
7900 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
7901 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
7903 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
7904 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
7908 * Clear all stats for this uid. Returns true if the uid is completely
7909 * inactive so can be dropped.
7911 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
7912 public boolean reset(long uptime, long realtime) {
7913 boolean active = false;
7915 mOnBatteryBackgroundTimeBase.init(uptime, realtime);
7916 mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime);
7918 if (mWifiRunningTimer != null) {
7919 active |= !mWifiRunningTimer.reset(false);
7920 active |= mWifiRunning;
7922 if (mFullWifiLockTimer != null) {
7923 active |= !mFullWifiLockTimer.reset(false);
7924 active |= mFullWifiLockOut;
7926 if (mWifiScanTimer != null) {
7927 active |= !mWifiScanTimer.reset(false);
7928 active |= mWifiScanStarted;
7930 if (mWifiBatchedScanTimer != null) {
7931 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7932 if (mWifiBatchedScanTimer[i] != null) {
7933 active |= !mWifiBatchedScanTimer[i].reset(false);
7936 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
7938 if (mWifiMulticastTimer != null) {
7939 active |= !mWifiMulticastTimer.reset(false);
7940 active |= mWifiMulticastEnabled;
7943 active |= !resetTimerIfNotNull(mAudioTurnedOnTimer, false);
7944 active |= !resetTimerIfNotNull(mVideoTurnedOnTimer, false);
7945 active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false);
7946 active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false);
7947 active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
7948 active |= !resetTimerIfNotNull(mForegroundServiceTimer, false);
7949 active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false);
7950 active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
7951 active |= !resetTimerIfNotNull(mBluetoothUnoptimizedScanTimer, false);
7952 if (mBluetoothScanResultCounter != null) {
7953 mBluetoothScanResultCounter.reset(false);
7955 if (mBluetoothScanResultBgCounter != null) {
7956 mBluetoothScanResultBgCounter.reset(false);
7959 if (mProcessStateTimer != null) {
7960 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
7961 if (mProcessStateTimer[i] != null) {
7962 active |= !mProcessStateTimer[i].reset(false);
7965 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT);
7967 if (mVibratorOnTimer != null) {
7968 if (mVibratorOnTimer.reset(false)) {
7969 mVibratorOnTimer.detach();
7970 mVibratorOnTimer = null;
7976 if (mUserActivityCounters != null) {
7977 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
7978 mUserActivityCounters[i].reset(false);
7982 if (mNetworkByteActivityCounters != null) {
7983 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
7984 mNetworkByteActivityCounters[i].reset(false);
7985 mNetworkPacketActivityCounters[i].reset(false);
7987 mMobileRadioActiveTime.reset(false);
7988 mMobileRadioActiveCount.reset(false);
7991 if (mWifiControllerActivity != null) {
7992 mWifiControllerActivity.reset(false);
7995 if (mBluetoothControllerActivity != null) {
7996 mBluetoothControllerActivity.reset(false);
7999 if (mModemControllerActivity != null) {
8000 mModemControllerActivity.reset(false);
8003 mUserCpuTime.reset(false);
8004 mSystemCpuTime.reset(false);
8006 if (mCpuClusterSpeedTimesUs != null) {
8007 for (LongSamplingCounter[] speeds : mCpuClusterSpeedTimesUs) {
8008 if (speeds != null) {
8009 for (LongSamplingCounter speed : speeds) {
8010 if (speed != null) {
8018 if (mCpuFreqTimeMs != null) {
8019 mCpuFreqTimeMs.reset(false);
8021 if (mScreenOffCpuFreqTimeMs != null) {
8022 mScreenOffCpuFreqTimeMs.reset(false);
8025 mCpuActiveTimeMs.reset(false);
8026 mCpuClusterTimesMs.reset(false);
8028 if (mProcStateTimeMs != null) {
8029 for (LongSamplingCounterArray counters : mProcStateTimeMs) {
8030 if (counters != null) {
8031 counters.reset(false);
8035 if (mProcStateScreenOffTimeMs != null) {
8036 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) {
8037 if (counters != null) {
8038 counters.reset(false);
8043 resetLongCounterIfNotNull(mMobileRadioApWakeupCount, false);
8044 resetLongCounterIfNotNull(mWifiRadioApWakeupCount, false);
8046 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
8047 for (int iw=wakeStats.size()-1; iw>=0; iw--) {
8048 Wakelock wl = wakeStats.valueAt(iw);
8050 wakeStats.removeAt(iw);
8055 mWakelockStats.cleanup();
8056 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap();
8057 for (int is=syncStats.size()-1; is>=0; is--) {
8058 DualTimer timer = syncStats.valueAt(is);
8059 if (timer.reset(false)) {
8060 syncStats.removeAt(is);
8066 mSyncStats.cleanup();
8067 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
8068 for (int ij=jobStats.size()-1; ij>=0; ij--) {
8069 DualTimer timer = jobStats.valueAt(ij);
8070 if (timer.reset(false)) {
8071 jobStats.removeAt(ij);
8077 mJobStats.cleanup();
8078 mJobCompletions.clear();
8080 mJobsDeferredEventCount.reset(false);
8081 mJobsDeferredCount.reset(false);
8082 mJobsFreshnessTimeMs.reset(false);
8083 for (int ij = 0; ij < JOB_FRESHNESS_BUCKETS.length; ij++) {
8084 if (mJobsFreshnessBuckets[ij] != null) {
8085 mJobsFreshnessBuckets[ij].reset(false);
8089 for (int ise=mSensorStats.size()-1; ise>=0; ise--) {
8090 Sensor s = mSensorStats.valueAt(ise);
8092 mSensorStats.removeAt(ise);
8098 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
8099 Proc proc = mProcessStats.valueAt(ip);
8102 mProcessStats.clear();
8103 if (mPids.size() > 0) {
8104 for (int i=mPids.size()-1; i>=0; i--) {
8105 Pid pid = mPids.valueAt(i);
8106 if (pid.mWakeNesting > 0) {
8113 if (mPackageStats.size() > 0) {
8114 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
8115 while (it.hasNext()) {
8116 Map.Entry<String, Pkg> pkgEntry = it.next();
8117 Pkg p = pkgEntry.getValue();
8119 if (p.mServiceStats.size() > 0) {
8120 Iterator<Map.Entry<String, Pkg.Serv>> it2
8121 = p.mServiceStats.entrySet().iterator();
8122 while (it2.hasNext()) {
8123 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
8124 servEntry.getValue().detach();
8128 mPackageStats.clear();
8131 mLastStepUserTime = mLastStepSystemTime = 0;
8132 mCurStepUserTime = mCurStepSystemTime = 0;
8135 if (mWifiRunningTimer != null) {
8136 mWifiRunningTimer.detach();
8138 if (mFullWifiLockTimer != null) {
8139 mFullWifiLockTimer.detach();
8141 if (mWifiScanTimer != null) {
8142 mWifiScanTimer.detach();
8144 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
8145 if (mWifiBatchedScanTimer[i] != null) {
8146 mWifiBatchedScanTimer[i].detach();
8149 if (mWifiMulticastTimer != null) {
8150 mWifiMulticastTimer.detach();
8152 if (mAudioTurnedOnTimer != null) {
8153 mAudioTurnedOnTimer.detach();
8154 mAudioTurnedOnTimer = null;
8156 if (mVideoTurnedOnTimer != null) {
8157 mVideoTurnedOnTimer.detach();
8158 mVideoTurnedOnTimer = null;
8160 if (mFlashlightTurnedOnTimer != null) {
8161 mFlashlightTurnedOnTimer.detach();
8162 mFlashlightTurnedOnTimer = null;
8164 if (mCameraTurnedOnTimer != null) {
8165 mCameraTurnedOnTimer.detach();
8166 mCameraTurnedOnTimer = null;
8168 if (mForegroundActivityTimer != null) {
8169 mForegroundActivityTimer.detach();
8170 mForegroundActivityTimer = null;
8172 if (mForegroundServiceTimer != null) {
8173 mForegroundServiceTimer.detach();
8174 mForegroundServiceTimer = null;
8176 if (mAggregatedPartialWakelockTimer != null) {
8177 mAggregatedPartialWakelockTimer.detach();
8178 mAggregatedPartialWakelockTimer = null;
8180 if (mBluetoothScanTimer != null) {
8181 mBluetoothScanTimer.detach();
8182 mBluetoothScanTimer = null;
8184 if (mBluetoothUnoptimizedScanTimer != null) {
8185 mBluetoothUnoptimizedScanTimer.detach();
8186 mBluetoothUnoptimizedScanTimer = null;
8188 if (mBluetoothScanResultCounter != null) {
8189 mBluetoothScanResultCounter.detach();
8190 mBluetoothScanResultCounter = null;
8192 if (mBluetoothScanResultBgCounter != null) {
8193 mBluetoothScanResultBgCounter.detach();
8194 mBluetoothScanResultBgCounter = null;
8196 if (mUserActivityCounters != null) {
8197 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
8198 mUserActivityCounters[i].detach();
8201 if (mNetworkByteActivityCounters != null) {
8202 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
8203 mNetworkByteActivityCounters[i].detach();
8204 mNetworkPacketActivityCounters[i].detach();
8208 if (mWifiControllerActivity != null) {
8209 mWifiControllerActivity.detach();
8212 if (mBluetoothControllerActivity != null) {
8213 mBluetoothControllerActivity.detach();
8216 if (mModemControllerActivity != null) {
8217 mModemControllerActivity.detach();
8222 mUserCpuTime.detach();
8223 mSystemCpuTime.detach();
8225 if (mCpuClusterSpeedTimesUs != null) {
8226 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) {
8227 if (cpuSpeeds != null) {
8228 for (LongSamplingCounter c : cpuSpeeds) {
8237 if (mCpuFreqTimeMs != null) {
8238 mCpuFreqTimeMs.detach();
8240 if (mScreenOffCpuFreqTimeMs != null) {
8241 mScreenOffCpuFreqTimeMs.detach();
8243 mCpuActiveTimeMs.detach();
8244 mCpuClusterTimesMs.detach();
8246 if (mProcStateTimeMs != null) {
8247 for (LongSamplingCounterArray counters : mProcStateTimeMs) {
8248 if (counters != null) {
8253 if (mProcStateScreenOffTimeMs != null) {
8254 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) {
8255 if (counters != null) {
8260 detachLongCounterIfNotNull(mMobileRadioApWakeupCount);
8261 detachLongCounterIfNotNull(mWifiRadioApWakeupCount);
8267 void writeJobCompletionsToParcelLocked(Parcel out) {
8268 int NJC = mJobCompletions.size();
8270 for (int ijc=0; ijc<NJC; ijc++) {
8271 out.writeString(mJobCompletions.keyAt(ijc));
8272 SparseIntArray types = mJobCompletions.valueAt(ijc);
8273 int NT = types.size();
8275 for (int it=0; it<NT; it++) {
8276 out.writeInt(types.keyAt(it));
8277 out.writeInt(types.valueAt(it));
8282 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) {
8283 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
8284 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
8286 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
8287 int NW = wakeStats.size();
8289 for (int iw=0; iw<NW; iw++) {
8290 out.writeString(wakeStats.keyAt(iw));
8291 Uid.Wakelock wakelock = wakeStats.valueAt(iw);
8292 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
8295 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap();
8296 int NS = syncStats.size();
8298 for (int is=0; is<NS; is++) {
8299 out.writeString(syncStats.keyAt(is));
8300 DualTimer timer = syncStats.valueAt(is);
8301 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
8304 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
8305 int NJ = jobStats.size();
8307 for (int ij=0; ij<NJ; ij++) {
8308 out.writeString(jobStats.keyAt(ij));
8309 DualTimer timer = jobStats.valueAt(ij);
8310 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
8313 writeJobCompletionsToParcelLocked(out);
8315 mJobsDeferredEventCount.writeToParcel(out);
8316 mJobsDeferredCount.writeToParcel(out);
8317 mJobsFreshnessTimeMs.writeToParcel(out);
8318 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
8319 Counter.writeCounterToParcel(out, mJobsFreshnessBuckets[i]);
8322 int NSE = mSensorStats.size();
8324 for (int ise=0; ise<NSE; ise++) {
8325 out.writeInt(mSensorStats.keyAt(ise));
8326 Uid.Sensor sensor = mSensorStats.valueAt(ise);
8327 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
8330 int NP = mProcessStats.size();
8332 for (int ip=0; ip<NP; ip++) {
8333 out.writeString(mProcessStats.keyAt(ip));
8334 Uid.Proc proc = mProcessStats.valueAt(ip);
8335 proc.writeToParcelLocked(out);
8338 out.writeInt(mPackageStats.size());
8339 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
8340 out.writeString(pkgEntry.getKey());
8341 Uid.Pkg pkg = pkgEntry.getValue();
8342 pkg.writeToParcelLocked(out);
8345 if (mWifiRunningTimer != null) {
8347 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
8351 if (mFullWifiLockTimer != null) {
8353 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
8357 if (mWifiScanTimer != null) {
8359 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
8363 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
8364 if (mWifiBatchedScanTimer[i] != null) {
8366 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
8371 if (mWifiMulticastTimer != null) {
8373 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
8378 if (mAudioTurnedOnTimer != null) {
8380 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
8384 if (mVideoTurnedOnTimer != null) {
8386 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
8390 if (mFlashlightTurnedOnTimer != null) {
8392 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
8396 if (mCameraTurnedOnTimer != null) {
8398 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
8402 if (mForegroundActivityTimer != null) {
8404 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
8408 if (mForegroundServiceTimer != null) {
8410 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs);
8414 if (mAggregatedPartialWakelockTimer != null) {
8416 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs);
8420 if (mBluetoothScanTimer != null) {
8422 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs);
8426 if (mBluetoothUnoptimizedScanTimer != null) {
8428 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs);
8432 if (mBluetoothScanResultCounter != null) {
8434 mBluetoothScanResultCounter.writeToParcel(out);
8438 if (mBluetoothScanResultBgCounter != null) {
8440 mBluetoothScanResultBgCounter.writeToParcel(out);
8444 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
8445 if (mProcessStateTimer[i] != null) {
8447 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs);
8452 if (mVibratorOnTimer != null) {
8454 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
8458 if (mUserActivityCounters != null) {
8460 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
8461 mUserActivityCounters[i].writeToParcel(out);
8466 if (mNetworkByteActivityCounters != null) {
8468 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
8469 mNetworkByteActivityCounters[i].writeToParcel(out);
8470 mNetworkPacketActivityCounters[i].writeToParcel(out);
8472 mMobileRadioActiveTime.writeToParcel(out);
8473 mMobileRadioActiveCount.writeToParcel(out);
8478 if (mWifiControllerActivity != null) {
8480 mWifiControllerActivity.writeToParcel(out, 0);
8485 if (mBluetoothControllerActivity != null) {
8487 mBluetoothControllerActivity.writeToParcel(out, 0);
8492 if (mModemControllerActivity != null) {
8494 mModemControllerActivity.writeToParcel(out, 0);
8499 mUserCpuTime.writeToParcel(out);
8500 mSystemCpuTime.writeToParcel(out);
8502 if (mCpuClusterSpeedTimesUs != null) {
8504 out.writeInt(mCpuClusterSpeedTimesUs.length);
8505 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) {
8506 if (cpuSpeeds != null) {
8508 out.writeInt(cpuSpeeds.length);
8509 for (LongSamplingCounter c : cpuSpeeds) {
8512 c.writeToParcel(out);
8525 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs);
8526 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs);
8528 mCpuActiveTimeMs.writeToParcel(out);
8529 mCpuClusterTimesMs.writeToParcel(out);
8531 if (mProcStateTimeMs != null) {
8532 out.writeInt(mProcStateTimeMs.length);
8533 for (LongSamplingCounterArray counters : mProcStateTimeMs) {
8534 LongSamplingCounterArray.writeToParcel(out, counters);
8539 if (mProcStateScreenOffTimeMs != null) {
8540 out.writeInt(mProcStateScreenOffTimeMs.length);
8541 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) {
8542 LongSamplingCounterArray.writeToParcel(out, counters);
8548 if (mMobileRadioApWakeupCount != null) {
8550 mMobileRadioApWakeupCount.writeToParcel(out);
8555 if (mWifiRadioApWakeupCount != null) {
8557 mWifiRadioApWakeupCount.writeToParcel(out);
8563 void readJobCompletionsFromParcelLocked(Parcel in) {
8564 int numJobCompletions = in.readInt();
8565 mJobCompletions.clear();
8566 for (int j = 0; j < numJobCompletions; j++) {
8567 String jobName = in.readString();
8568 int numTypes = in.readInt();
8570 SparseIntArray types = new SparseIntArray();
8571 for (int k = 0; k < numTypes; k++) {
8572 int type = in.readInt();
8573 int count = in.readInt();
8574 types.put(type, count);
8576 mJobCompletions.put(jobName, types);
8581 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
8582 mOnBatteryBackgroundTimeBase.readFromParcel(in);
8583 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in);
8585 int numWakelocks = in.readInt();
8586 mWakelockStats.clear();
8587 for (int j = 0; j < numWakelocks; j++) {
8588 String wakelockName = in.readString();
8589 Uid.Wakelock wakelock = new Wakelock(mBsi, this);
8590 wakelock.readFromParcelLocked(
8591 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in);
8592 mWakelockStats.add(wakelockName, wakelock);
8595 int numSyncs = in.readInt();
8597 for (int j = 0; j < numSyncs; j++) {
8598 String syncName = in.readString();
8599 if (in.readInt() != 0) {
8600 mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null,
8601 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in));
8605 int numJobs = in.readInt();
8607 for (int j = 0; j < numJobs; j++) {
8608 String jobName = in.readString();
8609 if (in.readInt() != 0) {
8610 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null,
8611 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in));
8615 readJobCompletionsFromParcelLocked(in);
8617 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase, in);
8618 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase, in);
8619 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8620 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
8621 mJobsFreshnessBuckets[i] = Counter.readCounterFromParcel(mBsi.mOnBatteryTimeBase,
8625 int numSensors = in.readInt();
8626 mSensorStats.clear();
8627 for (int k = 0; k < numSensors; k++) {
8628 int sensorNumber = in.readInt();
8629 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber);
8630 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase,
8632 mSensorStats.put(sensorNumber, sensor);
8635 int numProcs = in.readInt();
8636 mProcessStats.clear();
8637 for (int k = 0; k < numProcs; k++) {
8638 String processName = in.readString();
8639 Uid.Proc proc = new Proc(mBsi, processName);
8640 proc.readFromParcelLocked(in);
8641 mProcessStats.put(processName, proc);
8644 int numPkgs = in.readInt();
8645 mPackageStats.clear();
8646 for (int l = 0; l < numPkgs; l++) {
8647 String packageName = in.readString();
8648 Uid.Pkg pkg = new Pkg(mBsi);
8649 pkg.readFromParcelLocked(in);
8650 mPackageStats.put(packageName, pkg);
8653 mWifiRunning = false;
8654 if (in.readInt() != 0) {
8655 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING,
8656 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in);
8658 mWifiRunningTimer = null;
8660 mFullWifiLockOut = false;
8661 if (in.readInt() != 0) {
8662 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK,
8663 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in);
8665 mFullWifiLockTimer = null;
8667 mWifiScanStarted = false;
8668 if (in.readInt() != 0) {
8669 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN,
8670 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase,
8673 mWifiScanTimer = null;
8675 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
8676 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
8677 if (in.readInt() != 0) {
8678 makeWifiBatchedScanBin(i, in);
8680 mWifiBatchedScanTimer[i] = null;
8683 mWifiMulticastEnabled = false;
8684 if (in.readInt() != 0) {
8685 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED,
8686 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in);
8688 mWifiMulticastTimer = null;
8690 if (in.readInt() != 0) {
8691 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON,
8692 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
8694 mAudioTurnedOnTimer = null;
8696 if (in.readInt() != 0) {
8697 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON,
8698 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
8700 mVideoTurnedOnTimer = null;
8702 if (in.readInt() != 0) {
8703 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
8704 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
8706 mFlashlightTurnedOnTimer = null;
8708 if (in.readInt() != 0) {
8709 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON,
8710 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
8712 mCameraTurnedOnTimer = null;
8714 if (in.readInt() != 0) {
8715 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
8716 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in);
8718 mForegroundActivityTimer = null;
8720 if (in.readInt() != 0) {
8721 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
8722 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in);
8724 mForegroundServiceTimer = null;
8726 if (in.readInt() != 0) {
8727 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
8728 AGGREGATED_WAKE_TYPE_PARTIAL, null,
8729 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase,
8732 mAggregatedPartialWakelockTimer = null;
8734 if (in.readInt() != 0) {
8735 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
8736 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
8737 mOnBatteryBackgroundTimeBase, in);
8739 mBluetoothScanTimer = null;
8741 if (in.readInt() != 0) {
8742 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
8743 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
8744 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in);
8746 mBluetoothUnoptimizedScanTimer = null;
8748 if (in.readInt() != 0) {
8749 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in);
8751 mBluetoothScanResultCounter = null;
8753 if (in.readInt() != 0) {
8754 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in);
8756 mBluetoothScanResultBgCounter = null;
8758 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
8759 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
8760 if (in.readInt() != 0) {
8761 makeProcessState(i, in);
8763 mProcessStateTimer[i] = null;
8766 if (in.readInt() != 0) {
8767 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON,
8768 mBsi.mOnBatteryTimeBase, in);
8770 mVibratorOnTimer = null;
8772 if (in.readInt() != 0) {
8773 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
8774 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
8775 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in);
8778 mUserActivityCounters = null;
8780 if (in.readInt() != 0) {
8781 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
8782 mNetworkPacketActivityCounters
8783 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
8784 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
8785 mNetworkByteActivityCounters[i]
8786 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8787 mNetworkPacketActivityCounters[i]
8788 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8790 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8791 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8793 mNetworkByteActivityCounters = null;
8794 mNetworkPacketActivityCounters = null;
8797 if (in.readInt() != 0) {
8798 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
8799 NUM_WIFI_TX_LEVELS, in);
8801 mWifiControllerActivity = null;
8804 if (in.readInt() != 0) {
8805 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
8806 NUM_BT_TX_LEVELS, in);
8808 mBluetoothControllerActivity = null;
8811 if (in.readInt() != 0) {
8812 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
8813 ModemActivityInfo.TX_POWER_LEVELS, in);
8815 mModemControllerActivity = null;
8818 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8819 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8821 if (in.readInt() != 0) {
8822 int numCpuClusters = in.readInt();
8823 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) {
8824 throw new ParcelFormatException("Incompatible number of cpu clusters");
8827 mCpuClusterSpeedTimesUs = new LongSamplingCounter[numCpuClusters][];
8828 for (int cluster = 0; cluster < numCpuClusters; cluster++) {
8829 if (in.readInt() != 0) {
8830 int numSpeeds = in.readInt();
8831 if (mBsi.mPowerProfile != null &&
8832 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) {
8833 throw new ParcelFormatException("Incompatible number of cpu speeds");
8836 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds];
8837 mCpuClusterSpeedTimesUs[cluster] = cpuSpeeds;
8838 for (int speed = 0; speed < numSpeeds; speed++) {
8839 if (in.readInt() != 0) {
8840 cpuSpeeds[speed] = new LongSamplingCounter(
8841 mBsi.mOnBatteryTimeBase, in);
8845 mCpuClusterSpeedTimesUs[cluster] = null;
8849 mCpuClusterSpeedTimesUs = null;
8852 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase);
8853 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(
8854 in, mBsi.mOnBatteryScreenOffTimeBase);
8856 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8857 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in);
8859 int length = in.readInt();
8860 if (length == NUM_PROCESS_STATE) {
8861 mProcStateTimeMs = new LongSamplingCounterArray[length];
8862 for (int procState = 0; procState < length; ++procState) {
8863 mProcStateTimeMs[procState] = LongSamplingCounterArray.readFromParcel(
8864 in, mBsi.mOnBatteryTimeBase);
8867 mProcStateTimeMs = null;
8869 length = in.readInt();
8870 if (length == NUM_PROCESS_STATE) {
8871 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length];
8872 for (int procState = 0; procState < length; ++procState) {
8873 mProcStateScreenOffTimeMs[procState] = LongSamplingCounterArray.readFromParcel(
8874 in, mBsi.mOnBatteryScreenOffTimeBase);
8877 mProcStateScreenOffTimeMs = null;
8880 if (in.readInt() != 0) {
8881 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8883 mMobileRadioApWakeupCount = null;
8886 if (in.readInt() != 0) {
8887 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
8889 mWifiRadioApWakeupCount = null;
8893 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) {
8894 mJobsDeferredEventCount.addAtomic(1);
8895 mJobsDeferredCount.addAtomic(numDeferred);
8896 if (sinceLast != 0) {
8897 // Add the total time, which can be divided by the event count to get an average
8898 mJobsFreshnessTimeMs.addCountLocked(sinceLast);
8899 // Also keep track of how many times there were in these different buckets.
8900 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
8901 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) {
8902 if (mJobsFreshnessBuckets[i] == null) {
8903 mJobsFreshnessBuckets[i] = new Counter(
8904 mBsi.mOnBatteryTimeBase);
8906 mJobsFreshnessBuckets[i].addAtomic(1);
8914 * The statistics associated with a particular wake lock.
8916 public static class Wakelock extends BatteryStats.Uid.Wakelock {
8918 * BatteryStatsImpl that we are associated with.
8920 protected BatteryStatsImpl mBsi;
8923 * BatteryStatsImpl that we are associated with.
8928 * How long (in ms) this uid has been keeping the device partially awake.
8929 * Tracks both the total time and the time while the app was in the background.
8931 DualTimer mTimerPartial;
8934 * How long (in ms) this uid has been keeping the device fully awake.
8936 StopwatchTimer mTimerFull;
8939 * How long (in ms) this uid has had a window keeping the device awake.
8941 StopwatchTimer mTimerWindow;
8944 * How long (in ms) this uid has had a draw wake lock.
8946 StopwatchTimer mTimerDraw;
8948 public Wakelock(BatteryStatsImpl bsi, Uid uid) {
8954 * Reads a possibly null Timer from a Parcel. The timer is associated with the
8955 * proper timer pool from the given BatteryStatsImpl object.
8957 * @param in the Parcel to be read from.
8958 * return a new Timer, or null.
8960 private StopwatchTimer readStopwatchTimerFromParcel(int type,
8961 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) {
8962 if (in.readInt() == 0) {
8966 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in);
8970 * Reads a possibly null Timer from a Parcel. The timer is associated with the
8971 * proper timer pool from the given BatteryStatsImpl object.
8973 * @param in the Parcel to be read from.
8974 * return a new Timer, or null.
8976 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
8977 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
8978 if (in.readInt() == 0) {
8982 return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in);
8986 boolean wlactive = false;
8987 if (mTimerFull != null) {
8988 wlactive |= !mTimerFull.reset(false);
8990 if (mTimerPartial != null) {
8991 wlactive |= !mTimerPartial.reset(false);
8993 if (mTimerWindow != null) {
8994 wlactive |= !mTimerWindow.reset(false);
8996 if (mTimerDraw != null) {
8997 wlactive |= !mTimerDraw.reset(false);
9000 if (mTimerFull != null) {
9001 mTimerFull.detach();
9004 if (mTimerPartial != null) {
9005 mTimerPartial.detach();
9006 mTimerPartial = null;
9008 if (mTimerWindow != null) {
9009 mTimerWindow.detach();
9010 mTimerWindow = null;
9012 if (mTimerDraw != null) {
9013 mTimerDraw.detach();
9020 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase,
9021 TimeBase screenOffBgTimeBase, Parcel in) {
9022 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL,
9023 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in);
9024 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL,
9025 mBsi.mFullTimers, timeBase, in);
9026 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW,
9027 mBsi.mWindowTimers, timeBase, in);
9028 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW,
9029 mBsi.mDrawTimers, timeBase, in);
9032 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
9033 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
9034 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
9035 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
9036 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs);
9040 public Timer getWakeTime(int type) {
9042 case WAKE_TYPE_FULL: return mTimerFull;
9043 case WAKE_TYPE_PARTIAL: return mTimerPartial;
9044 case WAKE_TYPE_WINDOW: return mTimerWindow;
9045 case WAKE_TYPE_DRAW: return mTimerDraw;
9046 default: throw new IllegalArgumentException("type = " + type);
9051 public static class Sensor extends BatteryStats.Uid.Sensor {
9053 * BatteryStatsImpl that we are associated with.
9055 protected BatteryStatsImpl mBsi;
9058 * Uid that we are associated with.
9065 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) {
9071 private DualTimer readTimersFromParcel(
9072 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
9073 if (in.readInt() == 0) {
9077 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle);
9079 pool = new ArrayList<StopwatchTimer>();
9080 mBsi.mSensorTimers.put(mHandle, pool);
9082 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in);
9086 if (mTimer.reset(true)) {
9093 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
9094 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in);
9097 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
9098 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
9102 public Timer getSensorTime() {
9107 public Timer getSensorBackgroundTime() {
9108 if (mTimer == null) {
9111 return mTimer.getSubTimer();
9115 public int getHandle() {
9121 * The statistics associated with a particular process.
9123 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
9125 * BatteryStatsImpl that we are associated with.
9127 protected BatteryStatsImpl mBsi;
9130 * The name of this process.
9135 * Remains true until removed from the stats.
9137 boolean mActive = true;
9140 * Total time (in ms) spent executing in user code.
9145 * Total time (in ms) spent executing in kernel code.
9150 * Amount of time (in ms) the process was running in the foreground.
9152 long mForegroundTime;
9155 * Number of times the process has been started.
9160 * Number of times the process has crashed.
9165 * Number of times the process has had an ANR.
9170 * The amount of user time loaded from a previous save.
9172 long mLoadedUserTime;
9175 * The amount of system time loaded from a previous save.
9177 long mLoadedSystemTime;
9180 * The amount of foreground time loaded from a previous save.
9182 long mLoadedForegroundTime;
9185 * The number of times the process has started from a previous save.
9190 * Number of times the process has crashed from a previous save.
9192 int mLoadedNumCrashes;
9195 * Number of times the process has had an ANR from a previous save.
9200 * The amount of user time when last unplugged.
9202 long mUnpluggedUserTime;
9205 * The amount of system time when last unplugged.
9207 long mUnpluggedSystemTime;
9210 * The amount of foreground time since unplugged.
9212 long mUnpluggedForegroundTime;
9215 * The number of times the process has started before unplugged.
9217 int mUnpluggedStarts;
9220 * Number of times the process has crashed before unplugged.
9222 int mUnpluggedNumCrashes;
9225 * Number of times the process has had an ANR before unplugged.
9227 int mUnpluggedNumAnrs;
9229 ArrayList<ExcessivePower> mExcessivePower;
9231 public Proc(BatteryStatsImpl bsi, String name) {
9234 mBsi.mOnBatteryTimeBase.add(this);
9237 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
9238 mUnpluggedUserTime = mUserTime;
9239 mUnpluggedSystemTime = mSystemTime;
9240 mUnpluggedForegroundTime = mForegroundTime;
9241 mUnpluggedStarts = mStarts;
9242 mUnpluggedNumCrashes = mNumCrashes;
9243 mUnpluggedNumAnrs = mNumAnrs;
9246 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
9251 mBsi.mOnBatteryTimeBase.remove(this);
9254 public int countExcessivePowers() {
9255 return mExcessivePower != null ? mExcessivePower.size() : 0;
9258 public ExcessivePower getExcessivePower(int i) {
9259 if (mExcessivePower != null) {
9260 return mExcessivePower.get(i);
9265 public void addExcessiveCpu(long overTime, long usedTime) {
9266 if (mExcessivePower == null) {
9267 mExcessivePower = new ArrayList<ExcessivePower>();
9269 ExcessivePower ew = new ExcessivePower();
9270 ew.type = ExcessivePower.TYPE_CPU;
9271 ew.overTime = overTime;
9272 ew.usedTime = usedTime;
9273 mExcessivePower.add(ew);
9276 void writeExcessivePowerToParcelLocked(Parcel out) {
9277 if (mExcessivePower == null) {
9282 final int N = mExcessivePower.size();
9284 for (int i=0; i<N; i++) {
9285 ExcessivePower ew = mExcessivePower.get(i);
9286 out.writeInt(ew.type);
9287 out.writeLong(ew.overTime);
9288 out.writeLong(ew.usedTime);
9292 void readExcessivePowerFromParcelLocked(Parcel in) {
9293 final int N = in.readInt();
9295 mExcessivePower = null;
9300 throw new ParcelFormatException(
9301 "File corrupt: too many excessive power entries " + N);
9304 mExcessivePower = new ArrayList<>();
9305 for (int i=0; i<N; i++) {
9306 ExcessivePower ew = new ExcessivePower();
9307 ew.type = in.readInt();
9308 ew.overTime = in.readLong();
9309 ew.usedTime = in.readLong();
9310 mExcessivePower.add(ew);
9314 void writeToParcelLocked(Parcel out) {
9315 out.writeLong(mUserTime);
9316 out.writeLong(mSystemTime);
9317 out.writeLong(mForegroundTime);
9318 out.writeInt(mStarts);
9319 out.writeInt(mNumCrashes);
9320 out.writeInt(mNumAnrs);
9321 out.writeLong(mLoadedUserTime);
9322 out.writeLong(mLoadedSystemTime);
9323 out.writeLong(mLoadedForegroundTime);
9324 out.writeInt(mLoadedStarts);
9325 out.writeInt(mLoadedNumCrashes);
9326 out.writeInt(mLoadedNumAnrs);
9327 out.writeLong(mUnpluggedUserTime);
9328 out.writeLong(mUnpluggedSystemTime);
9329 out.writeLong(mUnpluggedForegroundTime);
9330 out.writeInt(mUnpluggedStarts);
9331 out.writeInt(mUnpluggedNumCrashes);
9332 out.writeInt(mUnpluggedNumAnrs);
9333 writeExcessivePowerToParcelLocked(out);
9336 void readFromParcelLocked(Parcel in) {
9337 mUserTime = in.readLong();
9338 mSystemTime = in.readLong();
9339 mForegroundTime = in.readLong();
9340 mStarts = in.readInt();
9341 mNumCrashes = in.readInt();
9342 mNumAnrs = in.readInt();
9343 mLoadedUserTime = in.readLong();
9344 mLoadedSystemTime = in.readLong();
9345 mLoadedForegroundTime = in.readLong();
9346 mLoadedStarts = in.readInt();
9347 mLoadedNumCrashes = in.readInt();
9348 mLoadedNumAnrs = in.readInt();
9349 mUnpluggedUserTime = in.readLong();
9350 mUnpluggedSystemTime = in.readLong();
9351 mUnpluggedForegroundTime = in.readLong();
9352 mUnpluggedStarts = in.readInt();
9353 mUnpluggedNumCrashes = in.readInt();
9354 mUnpluggedNumAnrs = in.readInt();
9355 readExcessivePowerFromParcelLocked(in);
9358 public void addCpuTimeLocked(int utime, int stime) {
9359 addCpuTimeLocked(utime, stime, mBsi.mOnBatteryTimeBase.isRunning());
9362 public void addCpuTimeLocked(int utime, int stime, boolean isRunning) {
9365 mSystemTime += stime;
9369 public void addForegroundTimeLocked(long ttime) {
9370 mForegroundTime += ttime;
9373 public void incStartsLocked() {
9377 public void incNumCrashesLocked() {
9381 public void incNumAnrsLocked() {
9386 public boolean isActive() {
9391 public long getUserTime(int which) {
9392 long val = mUserTime;
9393 if (which == STATS_CURRENT) {
9394 val -= mLoadedUserTime;
9395 } else if (which == STATS_SINCE_UNPLUGGED) {
9396 val -= mUnpluggedUserTime;
9402 public long getSystemTime(int which) {
9403 long val = mSystemTime;
9404 if (which == STATS_CURRENT) {
9405 val -= mLoadedSystemTime;
9406 } else if (which == STATS_SINCE_UNPLUGGED) {
9407 val -= mUnpluggedSystemTime;
9413 public long getForegroundTime(int which) {
9414 long val = mForegroundTime;
9415 if (which == STATS_CURRENT) {
9416 val -= mLoadedForegroundTime;
9417 } else if (which == STATS_SINCE_UNPLUGGED) {
9418 val -= mUnpluggedForegroundTime;
9424 public int getStarts(int which) {
9426 if (which == STATS_CURRENT) {
9427 val -= mLoadedStarts;
9428 } else if (which == STATS_SINCE_UNPLUGGED) {
9429 val -= mUnpluggedStarts;
9435 public int getNumCrashes(int which) {
9436 int val = mNumCrashes;
9437 if (which == STATS_CURRENT) {
9438 val -= mLoadedNumCrashes;
9439 } else if (which == STATS_SINCE_UNPLUGGED) {
9440 val -= mUnpluggedNumCrashes;
9446 public int getNumAnrs(int which) {
9448 if (which == STATS_CURRENT) {
9449 val -= mLoadedNumAnrs;
9450 } else if (which == STATS_SINCE_UNPLUGGED) {
9451 val -= mUnpluggedNumAnrs;
9458 * The statistics associated with a particular package.
9460 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
9462 * BatteryStatsImpl that we are associated with.
9464 protected BatteryStatsImpl mBsi;
9467 * Number of times wakeup alarms have occurred for this app.
9468 * On screen-off timebase starting in report v25.
9470 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();
9473 * The statics we have collected for this package's services.
9475 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>();
9477 public Pkg(BatteryStatsImpl bsi) {
9479 mBsi.mOnBatteryScreenOffTimeBase.add(this);
9482 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
9485 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
9489 mBsi.mOnBatteryScreenOffTimeBase.remove(this);
9492 void readFromParcelLocked(Parcel in) {
9493 int numWA = in.readInt();
9494 mWakeupAlarms.clear();
9495 for (int i=0; i<numWA; i++) {
9496 String tag = in.readString();
9497 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in));
9500 int numServs = in.readInt();
9501 mServiceStats.clear();
9502 for (int m = 0; m < numServs; m++) {
9503 String serviceName = in.readString();
9504 Uid.Pkg.Serv serv = new Serv(mBsi);
9505 mServiceStats.put(serviceName, serv);
9507 serv.readFromParcelLocked(in);
9511 void writeToParcelLocked(Parcel out) {
9512 int numWA = mWakeupAlarms.size();
9513 out.writeInt(numWA);
9514 for (int i=0; i<numWA; i++) {
9515 out.writeString(mWakeupAlarms.keyAt(i));
9516 mWakeupAlarms.valueAt(i).writeToParcel(out);
9519 final int NS = mServiceStats.size();
9521 for (int i=0; i<NS; i++) {
9522 out.writeString(mServiceStats.keyAt(i));
9523 Uid.Pkg.Serv serv = mServiceStats.valueAt(i);
9524 serv.writeToParcelLocked(out);
9529 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() {
9530 return mWakeupAlarms;
9533 public void noteWakeupAlarmLocked(String tag) {
9534 Counter c = mWakeupAlarms.get(tag);
9536 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase);
9537 mWakeupAlarms.put(tag, c);
9543 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
9544 return mServiceStats;
9548 * The statistics associated with a particular service.
9550 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
9552 * BatteryStatsImpl that we are associated with.
9554 protected BatteryStatsImpl mBsi;
9557 * The android package in which this service resides.
9562 * Total time (ms in battery uptime) the service has been left started.
9564 protected long mStartTime;
9567 * If service has been started and not yet stopped, this is
9568 * when it was started.
9570 protected long mRunningSince;
9573 * True if we are currently running.
9575 protected boolean mRunning;
9578 * Total number of times startService() has been called.
9580 protected int mStarts;
9583 * Total time (ms in battery uptime) the service has been left launched.
9585 protected long mLaunchedTime;
9588 * If service has been launched and not yet exited, this is
9589 * when it was launched (ms in battery uptime).
9591 protected long mLaunchedSince;
9594 * True if we are currently launched.
9596 protected boolean mLaunched;
9599 * Total number times the service has been launched.
9601 protected int mLaunches;
9604 * The amount of time spent started loaded from a previous save
9605 * (ms in battery uptime).
9607 protected long mLoadedStartTime;
9610 * The number of starts loaded from a previous save.
9612 protected int mLoadedStarts;
9615 * The number of launches loaded from a previous save.
9617 protected int mLoadedLaunches;
9620 * The amount of time spent started as of the last run (ms
9621 * in battery uptime).
9623 protected long mLastStartTime;
9626 * The number of starts as of the last run.
9628 protected int mLastStarts;
9631 * The number of launches as of the last run.
9633 protected int mLastLaunches;
9636 * The amount of time spent started when last unplugged (ms
9637 * in battery uptime).
9639 protected long mUnpluggedStartTime;
9642 * The number of starts when last unplugged.
9644 protected int mUnpluggedStarts;
9647 * The number of launches when last unplugged.
9649 protected int mUnpluggedLaunches;
9652 * Construct a Serv. Also adds it to the on-battery time base as a listener.
9654 public Serv(BatteryStatsImpl bsi) {
9656 mBsi.mOnBatteryTimeBase.add(this);
9659 public void onTimeStarted(long elapsedRealtime, long baseUptime,
9660 long baseRealtime) {
9661 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
9662 mUnpluggedStarts = mStarts;
9663 mUnpluggedLaunches = mLaunches;
9666 public void onTimeStopped(long elapsedRealtime, long baseUptime,
9667 long baseRealtime) {
9671 * Remove this Serv as a listener from the time base.
9673 public void detach() {
9674 mBsi.mOnBatteryTimeBase.remove(this);
9677 public void readFromParcelLocked(Parcel in) {
9678 mStartTime = in.readLong();
9679 mRunningSince = in.readLong();
9680 mRunning = in.readInt() != 0;
9681 mStarts = in.readInt();
9682 mLaunchedTime = in.readLong();
9683 mLaunchedSince = in.readLong();
9684 mLaunched = in.readInt() != 0;
9685 mLaunches = in.readInt();
9686 mLoadedStartTime = in.readLong();
9687 mLoadedStarts = in.readInt();
9688 mLoadedLaunches = in.readInt();
9692 mUnpluggedStartTime = in.readLong();
9693 mUnpluggedStarts = in.readInt();
9694 mUnpluggedLaunches = in.readInt();
9697 public void writeToParcelLocked(Parcel out) {
9698 out.writeLong(mStartTime);
9699 out.writeLong(mRunningSince);
9700 out.writeInt(mRunning ? 1 : 0);
9701 out.writeInt(mStarts);
9702 out.writeLong(mLaunchedTime);
9703 out.writeLong(mLaunchedSince);
9704 out.writeInt(mLaunched ? 1 : 0);
9705 out.writeInt(mLaunches);
9706 out.writeLong(mLoadedStartTime);
9707 out.writeInt(mLoadedStarts);
9708 out.writeInt(mLoadedLaunches);
9709 out.writeLong(mUnpluggedStartTime);
9710 out.writeInt(mUnpluggedStarts);
9711 out.writeInt(mUnpluggedLaunches);
9714 public long getLaunchTimeToNowLocked(long batteryUptime) {
9715 if (!mLaunched) return mLaunchedTime;
9716 return mLaunchedTime + batteryUptime - mLaunchedSince;
9719 public long getStartTimeToNowLocked(long batteryUptime) {
9720 if (!mRunning) return mStartTime;
9721 return mStartTime + batteryUptime - mRunningSince;
9724 public void startLaunchedLocked() {
9727 mLaunchedSince = mBsi.getBatteryUptimeLocked();
9732 public void stopLaunchedLocked() {
9734 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince;
9736 mLaunchedTime += time;
9744 public void startRunningLocked() {
9747 mRunningSince = mBsi.getBatteryUptimeLocked();
9752 public void stopRunningLocked() {
9754 long time = mBsi.getBatteryUptimeLocked() - mRunningSince;
9764 public BatteryStatsImpl getBatteryStats() {
9769 public int getLaunches(int which) {
9770 int val = mLaunches;
9771 if (which == STATS_CURRENT) {
9772 val -= mLoadedLaunches;
9773 } else if (which == STATS_SINCE_UNPLUGGED) {
9774 val -= mUnpluggedLaunches;
9780 public long getStartTime(long now, int which) {
9781 long val = getStartTimeToNowLocked(now);
9782 if (which == STATS_CURRENT) {
9783 val -= mLoadedStartTime;
9784 } else if (which == STATS_SINCE_UNPLUGGED) {
9785 val -= mUnpluggedStartTime;
9791 public int getStarts(int which) {
9793 if (which == STATS_CURRENT) {
9794 val -= mLoadedStarts;
9795 } else if (which == STATS_SINCE_UNPLUGGED) {
9796 val -= mUnpluggedStarts;
9803 final Serv newServiceStatsLocked() {
9804 return new Serv(mBsi);
9809 * Retrieve the statistics object for a particular process, creating
9812 public Proc getProcessStatsLocked(String name) {
9813 Proc ps = mProcessStats.get(name);
9815 ps = new Proc(mBsi, name);
9816 mProcessStats.put(name, ps);
9823 public void updateUidProcessStateLocked(int procState) {
9824 int uidRunningState;
9825 // Make special note of Foreground Services
9826 final boolean userAwareService =
9827 (procState == ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
9828 uidRunningState = BatteryStats.mapToInternalProcessState(procState);
9830 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) {
9834 final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime();
9835 if (mProcessState != uidRunningState) {
9836 final long uptimeMs = mBsi.mClocks.uptimeMillis();
9838 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
9839 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs);
9841 if (mBsi.trackPerProcStateCpuTimes()) {
9842 if (mBsi.mPendingUids.size() == 0) {
9843 mBsi.mExternalSync.scheduleReadProcStateCpuTimes(
9844 mBsi.mOnBatteryTimeBase.isRunning(),
9845 mBsi.mOnBatteryScreenOffTimeBase.isRunning(),
9846 mBsi.mConstants.PROC_STATE_CPU_TIMES_READ_DELAY_MS);
9847 mBsi.mNumCpuTimeReads++;
9849 mBsi.mNumBatchedCpuTimeReads++;
9851 if (mBsi.mPendingUids.indexOfKey(mUid) < 0
9852 || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) {
9853 mBsi.mPendingUids.put(mUid, mProcessState);
9856 mBsi.mPendingUids.clear();
9859 mProcessState = uidRunningState;
9860 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
9861 if (mProcessStateTimer[uidRunningState] == null) {
9862 makeProcessState(uidRunningState, null);
9864 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs);
9867 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
9868 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
9871 if (userAwareService != mInForegroundService) {
9872 if (userAwareService) {
9873 noteForegroundServiceResumedLocked(elapsedRealtimeMs);
9875 noteForegroundServicePausedLocked(elapsedRealtimeMs);
9877 mInForegroundService = userAwareService;
9881 /** Whether to consider Uid to be in the background for background timebase purposes. */
9882 public boolean isInBackground() {
9883 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is
9884 // also considered to be 'background' for our purposes, because it's not foreground.
9885 return mProcessState >= PROCESS_STATE_BACKGROUND;
9888 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) {
9889 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground();
9890 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
9893 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) {
9894 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground();
9895 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
9898 public SparseArray<? extends Pid> getPidStats() {
9902 public Pid getPidStatsLocked(int pid) {
9903 Pid p = mPids.get(pid);
9912 * Retrieve the statistics object for a particular service, creating
9915 public Pkg getPackageStatsLocked(String name) {
9916 Pkg ps = mPackageStats.get(name);
9919 mPackageStats.put(name, ps);
9926 * Retrieve the statistics object for a particular service, creating
9929 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
9930 Pkg ps = getPackageStatsLocked(pkg);
9931 Pkg.Serv ss = ps.mServiceStats.get(serv);
9933 ss = ps.newServiceStatsLocked();
9934 ps.mServiceStats.put(serv, ss);
9940 public void readSyncSummaryFromParcelLocked(String name, Parcel in) {
9941 DualTimer timer = mSyncStats.instantiateObject();
9942 timer.readSummaryFromParcelLocked(in);
9943 mSyncStats.add(name, timer);
9946 public void readJobSummaryFromParcelLocked(String name, Parcel in) {
9947 DualTimer timer = mJobStats.instantiateObject();
9948 timer.readSummaryFromParcelLocked(in);
9949 mJobStats.add(name, timer);
9952 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) {
9953 Wakelock wl = new Wakelock(mBsi, this);
9954 mWakelockStats.add(wlName, wl);
9955 if (in.readInt() != 0) {
9956 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
9958 if (in.readInt() != 0) {
9959 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
9961 if (in.readInt() != 0) {
9962 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
9964 if (in.readInt() != 0) {
9965 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
9969 public DualTimer getSensorTimerLocked(int sensor, boolean create) {
9970 Sensor se = mSensorStats.get(sensor);
9975 se = new Sensor(mBsi, this, sensor);
9976 mSensorStats.put(sensor, se);
9978 DualTimer t = se.mTimer;
9982 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor);
9983 if (timers == null) {
9984 timers = new ArrayList<StopwatchTimer>();
9985 mBsi.mSensorTimers.put(sensor, timers);
9987 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers,
9988 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
9993 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) {
9994 DualTimer t = mSyncStats.startObject(name);
9996 t.startRunningLocked(elapsedRealtimeMs);
9997 StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, getUid(), null, name,
9998 StatsLog.SYNC_STATE_CHANGED__STATE__ON);
10002 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) {
10003 DualTimer t = mSyncStats.stopObject(name);
10005 t.stopRunningLocked(elapsedRealtimeMs);
10006 if (!t.isRunningLocked()) { // only tell statsd if truly stopped
10007 StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, getUid(), null, name,
10008 StatsLog.SYNC_STATE_CHANGED__STATE__OFF);
10013 public void noteStartJobLocked(String name, long elapsedRealtimeMs) {
10014 DualTimer t = mJobStats.startObject(name);
10016 t.startRunningLocked(elapsedRealtimeMs);
10017 StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), null,
10018 name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED);
10022 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) {
10023 DualTimer t = mJobStats.stopObject(name);
10025 t.stopRunningLocked(elapsedRealtimeMs);
10026 if (!t.isRunningLocked()) { // only tell statsd if truly stopped
10027 StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), null,
10028 name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED);
10031 if (mBsi.mOnBatteryTimeBase.isRunning()) {
10032 SparseIntArray types = mJobCompletions.get(name);
10033 if (types == null) {
10034 types = new SparseIntArray();
10035 mJobCompletions.put(name, types);
10037 int last = types.get(stopReason, 0);
10038 types.put(stopReason, last + 1);
10042 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) {
10047 case WAKE_TYPE_PARTIAL: {
10048 DualTimer t = wl.mTimerPartial;
10050 t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL,
10051 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase,
10052 mOnBatteryScreenOffBackgroundTimeBase);
10053 wl.mTimerPartial = t;
10057 case WAKE_TYPE_FULL: {
10058 StopwatchTimer t = wl.mTimerFull;
10060 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL,
10061 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase);
10066 case WAKE_TYPE_WINDOW: {
10067 StopwatchTimer t = wl.mTimerWindow;
10069 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW,
10070 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase);
10071 wl.mTimerWindow = t;
10075 case WAKE_TYPE_DRAW: {
10076 StopwatchTimer t = wl.mTimerDraw;
10078 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW,
10079 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase);
10085 throw new IllegalArgumentException("type=" + type);
10089 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
10090 Wakelock wl = mWakelockStats.startObject(name);
10092 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs);
10094 if (type == WAKE_TYPE_PARTIAL) {
10095 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs);
10097 Pid p = getPidStatsLocked(pid);
10098 if (p.mWakeNesting++ == 0) {
10099 p.mWakeStartMs = elapsedRealtimeMs;
10105 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
10106 Wakelock wl = mWakelockStats.stopObject(name);
10108 StopwatchTimer wlt = getWakelockTimerLocked(wl, type);
10109 wlt.stopRunningLocked(elapsedRealtimeMs);
10111 if (type == WAKE_TYPE_PARTIAL) {
10112 if (mAggregatedPartialWakelockTimer != null) {
10113 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs);
10116 Pid p = mPids.get(pid);
10117 if (p != null && p.mWakeNesting > 0) {
10118 if (p.mWakeNesting-- == 1) {
10119 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
10120 p.mWakeStartMs = 0;
10127 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
10128 Proc p = getProcessStatsLocked(proc);
10130 p.addExcessiveCpu(overTime, usedTime);
10134 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
10135 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true);
10136 t.startRunningLocked(elapsedRealtimeMs);
10137 if (sensor != Sensor.GPS) {
10138 StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, getUid(), null, sensor,
10139 StatsLog.SENSOR_STATE_CHANGED__STATE__ON);
10143 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
10144 // Don't create a timer if one doesn't already exist
10145 DualTimer t = getSensorTimerLocked(sensor, false);
10147 t.stopRunningLocked(elapsedRealtimeMs);
10148 if (sensor != Sensor.GPS) {
10149 StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, getUid(), null,
10150 sensor, StatsLog.SENSOR_STATE_CHANGED__STATE__OFF);
10155 public void noteStartGps(long elapsedRealtimeMs) {
10156 noteStartSensor(Sensor.GPS, elapsedRealtimeMs);
10159 public void noteStopGps(long elapsedRealtimeMs) {
10160 noteStopSensor(Sensor.GPS, elapsedRealtimeMs);
10163 public BatteryStatsImpl getBatteryStats() {
10168 public long[] getCpuFreqs() {
10172 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb,
10173 UserInfoProvider userInfoProvider) {
10174 this(new SystemClocks(), systemDir, handler, cb, userInfoProvider);
10177 private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler,
10178 PlatformIdleStateCallback cb,
10179 UserInfoProvider userInfoProvider) {
10182 if (systemDir != null) {
10183 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"),
10184 new File(systemDir, "batterystats.bin.tmp"));
10188 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
10189 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
10190 mHandler = new MyHandler(handler.getLooper());
10191 mConstants = new Constants(mHandler);
10193 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase);
10194 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase);
10195 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
10196 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null,
10197 mOnBatteryTimeBase);
10199 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase);
10200 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null,
10201 mOnBatteryTimeBase);
10202 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null,
10203 mOnBatteryTimeBase);
10204 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase);
10205 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase);
10206 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase);
10207 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase);
10208 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
10209 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null,
10210 mOnBatteryTimeBase);
10212 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null,
10213 mOnBatteryTimeBase);
10214 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
10215 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null,
10216 mOnBatteryTimeBase);
10218 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
10219 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
10220 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
10222 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS);
10223 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
10225 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
10226 ModemActivityInfo.TX_POWER_LEVELS);
10227 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase);
10228 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null,
10229 mOnBatteryTimeBase);
10230 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
10231 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
10232 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
10233 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null,
10234 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase);
10235 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase);
10236 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase);
10237 for (int i=0; i<NUM_WIFI_STATES; i++) {
10238 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null,
10239 mOnBatteryTimeBase);
10241 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
10242 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null,
10243 mOnBatteryTimeBase);
10245 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
10246 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null,
10247 mOnBatteryTimeBase);
10249 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, mOnBatteryTimeBase);
10250 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
10251 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null,
10252 mOnBatteryTimeBase);
10254 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase);
10255 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase);
10256 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase);
10257 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase);
10258 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase);
10259 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase);
10260 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
10261 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
10262 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
10263 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
10264 mOnBattery = mOnBatteryInternal = false;
10265 long uptime = mClocks.uptimeMillis() * 1000;
10266 long realtime = mClocks.elapsedRealtime() * 1000;
10267 initTimes(uptime, realtime);
10268 mStartPlatformVersion = mEndPlatformVersion = Build.ID;
10269 mDischargeStartLevel = 0;
10270 mDischargeUnplugLevel = 0;
10271 mDischargePlugLevel = -1;
10272 mDischargeCurrentLevel = 0;
10273 mCurrentBatteryLevel = 0;
10275 clearHistoryLocked();
10276 updateDailyDeadlineLocked();
10277 mPlatformIdleStateCallback = cb;
10278 mUserInfoProvider = userInfoProvider;
10281 public BatteryStatsImpl(Parcel p) {
10282 this(new SystemClocks(), p);
10285 public BatteryStatsImpl(Clocks clocks, Parcel p) {
10288 mCheckinFile = null;
10291 mExternalSync = null;
10292 mConstants = new Constants(mHandler);
10293 clearHistoryLocked();
10295 mPlatformIdleStateCallback = null;
10298 public void setPowerProfileLocked(PowerProfile profile) {
10299 mPowerProfile = profile;
10301 // We need to initialize the KernelCpuSpeedReaders to read from
10302 // the first cpu of each core. Once we have the PowerProfile, we have access to this
10304 final int numClusters = mPowerProfile.getNumCpuClusters();
10305 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
10306 int firstCpuOfCluster = 0;
10307 for (int i = 0; i < numClusters; i++) {
10308 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i);
10309 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
10311 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i);
10314 if (mEstimatedBatteryCapacity == -1) {
10315 // Initialize the estimated battery capacity to a known preset one.
10316 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity();
10320 public void setCallback(BatteryCallback cb) {
10324 public void setRadioScanningTimeoutLocked(long timeout) {
10325 if (mPhoneSignalScanningTimer != null) {
10326 mPhoneSignalScanningTimer.setTimeout(timeout);
10330 public void setExternalStatsSyncLocked(ExternalStatsSync sync) {
10331 mExternalSync = sync;
10334 public void updateDailyDeadlineLocked() {
10335 // Get the current time.
10336 long currentTime = mDailyStartTime = System.currentTimeMillis();
10337 Calendar calDeadline = Calendar.getInstance();
10338 calDeadline.setTimeInMillis(currentTime);
10340 // Move time up to the next day, ranging from 1am to 3pm.
10341 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1);
10342 calDeadline.set(Calendar.MILLISECOND, 0);
10343 calDeadline.set(Calendar.SECOND, 0);
10344 calDeadline.set(Calendar.MINUTE, 0);
10345 calDeadline.set(Calendar.HOUR_OF_DAY, 1);
10346 mNextMinDailyDeadline = calDeadline.getTimeInMillis();
10347 calDeadline.set(Calendar.HOUR_OF_DAY, 3);
10348 mNextMaxDailyDeadline = calDeadline.getTimeInMillis();
10351 public void recordDailyStatsIfNeededLocked(boolean settled) {
10352 long currentTime = System.currentTimeMillis();
10353 if (currentTime >= mNextMaxDailyDeadline) {
10354 recordDailyStatsLocked();
10355 } else if (settled && currentTime >= mNextMinDailyDeadline) {
10356 recordDailyStatsLocked();
10357 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) {
10358 recordDailyStatsLocked();
10362 public void recordDailyStatsLocked() {
10363 DailyItem item = new DailyItem();
10364 item.mStartTime = mDailyStartTime;
10365 item.mEndTime = System.currentTimeMillis();
10366 boolean hasData = false;
10367 if (mDailyDischargeStepTracker.mNumStepDurations > 0) {
10369 item.mDischargeSteps = new LevelStepTracker(
10370 mDailyDischargeStepTracker.mNumStepDurations,
10371 mDailyDischargeStepTracker.mStepDurations);
10373 if (mDailyChargeStepTracker.mNumStepDurations > 0) {
10375 item.mChargeSteps = new LevelStepTracker(
10376 mDailyChargeStepTracker.mNumStepDurations,
10377 mDailyChargeStepTracker.mStepDurations);
10379 if (mDailyPackageChanges != null) {
10381 item.mPackageChanges = mDailyPackageChanges;
10382 mDailyPackageChanges = null;
10384 mDailyDischargeStepTracker.init();
10385 mDailyChargeStepTracker.init();
10386 updateDailyDeadlineLocked();
10389 final long startTime = SystemClock.uptimeMillis();
10390 mDailyItems.add(item);
10391 while (mDailyItems.size() > MAX_DAILY_ITEMS) {
10392 mDailyItems.remove(0);
10394 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
10396 XmlSerializer out = new FastXmlSerializer();
10397 out.setOutput(memStream, StandardCharsets.UTF_8.name());
10398 writeDailyItemsLocked(out);
10399 final long initialTime = SystemClock.uptimeMillis() - startTime;
10400 BackgroundThread.getHandler().post(new Runnable() {
10402 public void run() {
10403 synchronized (mCheckinFile) {
10404 final long startTime2 = SystemClock.uptimeMillis();
10405 FileOutputStream stream = null;
10407 stream = mDailyFile.startWrite();
10408 memStream.writeTo(stream);
10410 FileUtils.sync(stream);
10412 mDailyFile.finishWrite(stream);
10413 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
10414 "batterystats-daily",
10415 initialTime + SystemClock.uptimeMillis() - startTime2);
10416 } catch (IOException e) {
10417 Slog.w("BatteryStats",
10418 "Error writing battery daily items", e);
10419 mDailyFile.failWrite(stream);
10424 } catch (IOException e) {
10429 private void writeDailyItemsLocked(XmlSerializer out) throws IOException {
10430 StringBuilder sb = new StringBuilder(64);
10431 out.startDocument(null, true);
10432 out.startTag(null, "daily-items");
10433 for (int i=0; i<mDailyItems.size(); i++) {
10434 final DailyItem dit = mDailyItems.get(i);
10435 out.startTag(null, "item");
10436 out.attribute(null, "start", Long.toString(dit.mStartTime));
10437 out.attribute(null, "end", Long.toString(dit.mEndTime));
10438 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb);
10439 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb);
10440 if (dit.mPackageChanges != null) {
10441 for (int j=0; j<dit.mPackageChanges.size(); j++) {
10442 PackageChange pc = dit.mPackageChanges.get(j);
10444 out.startTag(null, "upd");
10445 out.attribute(null, "pkg", pc.mPackageName);
10446 out.attribute(null, "ver", Long.toString(pc.mVersionCode));
10447 out.endTag(null, "upd");
10449 out.startTag(null, "rem");
10450 out.attribute(null, "pkg", pc.mPackageName);
10451 out.endTag(null, "rem");
10455 out.endTag(null, "item");
10457 out.endTag(null, "daily-items");
10461 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps,
10462 StringBuilder tmpBuilder) throws IOException {
10463 if (steps != null) {
10464 out.startTag(null, tag);
10465 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations));
10466 for (int i=0; i<steps.mNumStepDurations; i++) {
10467 out.startTag(null, "s");
10468 tmpBuilder.setLength(0);
10469 steps.encodeEntryAt(i, tmpBuilder);
10470 out.attribute(null, "v", tmpBuilder.toString());
10471 out.endTag(null, "s");
10473 out.endTag(null, tag);
10477 public void readDailyStatsLocked() {
10478 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile());
10479 mDailyItems.clear();
10480 FileInputStream stream;
10482 stream = mDailyFile.openRead();
10483 } catch (FileNotFoundException e) {
10487 XmlPullParser parser = Xml.newPullParser();
10488 parser.setInput(stream, StandardCharsets.UTF_8.name());
10489 readDailyItemsLocked(parser);
10490 } catch (XmlPullParserException e) {
10494 } catch (IOException e) {
10499 private void readDailyItemsLocked(XmlPullParser parser) {
10502 while ((type = parser.next()) != XmlPullParser.START_TAG
10503 && type != XmlPullParser.END_DOCUMENT) {
10507 if (type != XmlPullParser.START_TAG) {
10508 throw new IllegalStateException("no start tag found");
10511 int outerDepth = parser.getDepth();
10512 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
10513 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
10514 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
10518 String tagName = parser.getName();
10519 if (tagName.equals("item")) {
10520 readDailyItemTagLocked(parser);
10522 Slog.w(TAG, "Unknown element under <daily-items>: "
10523 + parser.getName());
10524 XmlUtils.skipCurrentTag(parser);
10528 } catch (IllegalStateException e) {
10529 Slog.w(TAG, "Failed parsing daily " + e);
10530 } catch (NullPointerException e) {
10531 Slog.w(TAG, "Failed parsing daily " + e);
10532 } catch (NumberFormatException e) {
10533 Slog.w(TAG, "Failed parsing daily " + e);
10534 } catch (XmlPullParserException e) {
10535 Slog.w(TAG, "Failed parsing daily " + e);
10536 } catch (IOException e) {
10537 Slog.w(TAG, "Failed parsing daily " + e);
10538 } catch (IndexOutOfBoundsException e) {
10539 Slog.w(TAG, "Failed parsing daily " + e);
10543 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException,
10544 XmlPullParserException, IOException {
10545 DailyItem dit = new DailyItem();
10546 String attr = parser.getAttributeValue(null, "start");
10547 if (attr != null) {
10548 dit.mStartTime = Long.parseLong(attr);
10550 attr = parser.getAttributeValue(null, "end");
10551 if (attr != null) {
10552 dit.mEndTime = Long.parseLong(attr);
10554 int outerDepth = parser.getDepth();
10556 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
10557 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
10558 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
10562 String tagName = parser.getName();
10563 if (tagName.equals("dis")) {
10564 readDailyItemTagDetailsLocked(parser, dit, false, "dis");
10565 } else if (tagName.equals("chg")) {
10566 readDailyItemTagDetailsLocked(parser, dit, true, "chg");
10567 } else if (tagName.equals("upd")) {
10568 if (dit.mPackageChanges == null) {
10569 dit.mPackageChanges = new ArrayList<>();
10571 PackageChange pc = new PackageChange();
10573 pc.mPackageName = parser.getAttributeValue(null, "pkg");
10574 String verStr = parser.getAttributeValue(null, "ver");
10575 pc.mVersionCode = verStr != null ? Long.parseLong(verStr) : 0;
10576 dit.mPackageChanges.add(pc);
10577 XmlUtils.skipCurrentTag(parser);
10578 } else if (tagName.equals("rem")) {
10579 if (dit.mPackageChanges == null) {
10580 dit.mPackageChanges = new ArrayList<>();
10582 PackageChange pc = new PackageChange();
10583 pc.mUpdate = false;
10584 pc.mPackageName = parser.getAttributeValue(null, "pkg");
10585 dit.mPackageChanges.add(pc);
10586 XmlUtils.skipCurrentTag(parser);
10588 Slog.w(TAG, "Unknown element under <item>: "
10589 + parser.getName());
10590 XmlUtils.skipCurrentTag(parser);
10593 mDailyItems.add(dit);
10596 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge,
10598 throws NumberFormatException, XmlPullParserException, IOException {
10599 final String numAttr = parser.getAttributeValue(null, "n");
10600 if (numAttr == null) {
10601 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription());
10602 XmlUtils.skipCurrentTag(parser);
10605 final int num = Integer.parseInt(numAttr);
10606 LevelStepTracker steps = new LevelStepTracker(num);
10608 dit.mChargeSteps = steps;
10610 dit.mDischargeSteps = steps;
10613 int outerDepth = parser.getDepth();
10615 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
10616 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
10617 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
10621 String tagName = parser.getName();
10622 if ("s".equals(tagName)) {
10624 String valueAttr = parser.getAttributeValue(null, "v");
10625 if (valueAttr != null) {
10626 steps.decodeEntryAt(i, valueAttr);
10631 Slog.w(TAG, "Unknown element under <" + tag + ">: "
10632 + parser.getName());
10633 XmlUtils.skipCurrentTag(parser);
10636 steps.mNumStepDurations = i;
10640 public DailyItem getDailyItemLocked(int daysAgo) {
10641 int index = mDailyItems.size()-1-daysAgo;
10642 return index >= 0 ? mDailyItems.get(index) : null;
10646 public long getCurrentDailyStartTime() {
10647 return mDailyStartTime;
10651 public long getNextMinDailyDeadline() {
10652 return mNextMinDailyDeadline;
10656 public long getNextMaxDailyDeadline() {
10657 return mNextMaxDailyDeadline;
10661 public boolean startIteratingOldHistoryLocked() {
10662 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
10663 + " pos=" + mHistoryBuffer.dataPosition());
10664 if ((mHistoryIterator = mHistory) == null) {
10667 mHistoryBuffer.setDataPosition(0);
10668 mHistoryReadTmp.clear();
10669 mReadOverflow = false;
10670 mIteratingHistory = true;
10675 public boolean getNextOldHistoryLocked(HistoryItem out) {
10676 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
10678 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
10679 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
10681 HistoryItem cur = mHistoryIterator;
10683 if (!mReadOverflow && !end) {
10684 Slog.w(TAG, "Old history ends before new history!");
10689 mHistoryIterator = cur.next;
10690 if (!mReadOverflow) {
10692 Slog.w(TAG, "New history ends before old history!");
10693 } else if (!out.same(mHistoryReadTmp)) {
10694 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
10695 pw.println("Histories differ!");
10696 pw.println("Old history:");
10697 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true);
10698 pw.println("New history:");
10699 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false,
10708 public void finishIteratingOldHistoryLocked() {
10709 mIteratingHistory = false;
10710 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
10711 mHistoryIterator = null;
10714 public int getHistoryTotalSize() {
10715 return MAX_HISTORY_BUFFER;
10718 public int getHistoryUsedSize() {
10719 return mHistoryBuffer.dataSize();
10723 public boolean startIteratingHistoryLocked() {
10724 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
10725 + " pos=" + mHistoryBuffer.dataPosition());
10726 if (mHistoryBuffer.dataSize() <= 0) {
10729 mHistoryBuffer.setDataPosition(0);
10730 mReadOverflow = false;
10731 mIteratingHistory = true;
10732 mReadHistoryStrings = new String[mHistoryTagPool.size()];
10733 mReadHistoryUids = new int[mHistoryTagPool.size()];
10734 mReadHistoryChars = 0;
10735 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
10736 final HistoryTag tag = ent.getKey();
10737 final int idx = ent.getValue();
10738 mReadHistoryStrings[idx] = tag.string;
10739 mReadHistoryUids[idx] = tag.uid;
10740 mReadHistoryChars += tag.string.length() + 1;
10746 public int getHistoryStringPoolSize() {
10747 return mReadHistoryStrings.length;
10751 public int getHistoryStringPoolBytes() {
10752 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
10753 // Each string character is 2 bytes.
10754 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
10758 public String getHistoryTagPoolString(int index) {
10759 return mReadHistoryStrings[index];
10763 public int getHistoryTagPoolUid(int index) {
10764 return mReadHistoryUids[index];
10768 public boolean getNextHistoryLocked(HistoryItem out) {
10769 final int pos = mHistoryBuffer.dataPosition();
10773 boolean end = pos >= mHistoryBuffer.dataSize();
10778 final long lastRealtime = out.time;
10779 final long lastWalltime = out.currentTime;
10780 readHistoryDelta(mHistoryBuffer, out);
10781 if (out.cmd != HistoryItem.CMD_CURRENT_TIME
10782 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
10783 out.currentTime = lastWalltime + (out.time - lastRealtime);
10789 public void finishIteratingHistoryLocked() {
10790 mIteratingHistory = false;
10791 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
10792 mReadHistoryStrings = null;
10796 public long getHistoryBaseTime() {
10797 return mHistoryBaseTime;
10801 public int getStartCount() {
10802 return mStartCount;
10805 public boolean isOnBattery() {
10809 public boolean isCharging() {
10813 public boolean isScreenOn(int state) {
10814 return state == Display.STATE_ON || state == Display.STATE_VR
10815 || state == Display.STATE_ON_SUSPEND;
10818 public boolean isScreenOff(int state) {
10819 return state == Display.STATE_OFF;
10822 public boolean isScreenDoze(int state) {
10823 return state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND;
10826 void initTimes(long uptime, long realtime) {
10827 mStartClockTime = System.currentTimeMillis();
10828 mOnBatteryTimeBase.init(uptime, realtime);
10829 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
10832 mRealtimeStart = realtime;
10833 mUptimeStart = uptime;
10836 void initDischarge() {
10837 mLowDischargeAmountSinceCharge = 0;
10838 mHighDischargeAmountSinceCharge = 0;
10839 mDischargeAmountScreenOn = 0;
10840 mDischargeAmountScreenOnSinceCharge = 0;
10841 mDischargeAmountScreenOff = 0;
10842 mDischargeAmountScreenOffSinceCharge = 0;
10843 mDischargeAmountScreenDoze = 0;
10844 mDischargeAmountScreenDozeSinceCharge = 0;
10845 mDischargeStepTracker.init();
10846 mChargeStepTracker.init();
10847 mDischargeScreenOffCounter.reset(false);
10848 mDischargeScreenDozeCounter.reset(false);
10849 mDischargeLightDozeCounter.reset(false);
10850 mDischargeDeepDozeCounter.reset(false);
10851 mDischargeCounter.reset(false);
10854 public void resetAllStatsCmdLocked() {
10855 resetAllStatsLocked();
10856 final long mSecUptime = mClocks.uptimeMillis();
10857 long uptime = mSecUptime * 1000;
10858 long mSecRealtime = mClocks.elapsedRealtime();
10859 long realtime = mSecRealtime * 1000;
10860 mDischargeStartLevel = mHistoryCur.batteryLevel;
10861 pullPendingStateUpdatesLocked();
10862 addHistoryRecordLocked(mSecRealtime, mSecUptime);
10863 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
10864 = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
10865 mOnBatteryTimeBase.reset(uptime, realtime);
10866 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
10867 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
10868 if (isScreenOn(mScreenState)) {
10869 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
10870 mDischargeScreenDozeUnplugLevel = 0;
10871 mDischargeScreenOffUnplugLevel = 0;
10872 } else if (isScreenDoze(mScreenState)) {
10873 mDischargeScreenOnUnplugLevel = 0;
10874 mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel;
10875 mDischargeScreenOffUnplugLevel = 0;
10877 mDischargeScreenOnUnplugLevel = 0;
10878 mDischargeScreenDozeUnplugLevel = 0;
10879 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
10881 mDischargeAmountScreenOn = 0;
10882 mDischargeAmountScreenOff = 0;
10883 mDischargeAmountScreenDoze = 0;
10885 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
10888 private void resetAllStatsLocked() {
10889 final long uptimeMillis = mClocks.uptimeMillis();
10890 final long elapsedRealtimeMillis = mClocks.elapsedRealtime();
10892 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000);
10893 mScreenOnTimer.reset(false);
10894 mScreenDozeTimer.reset(false);
10895 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
10896 mScreenBrightnessTimer[i].reset(false);
10899 if (mPowerProfile != null) {
10900 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity();
10902 mEstimatedBatteryCapacity = -1;
10904 mMinLearnedBatteryCapacity = -1;
10905 mMaxLearnedBatteryCapacity = -1;
10906 mInteractiveTimer.reset(false);
10907 mPowerSaveModeEnabledTimer.reset(false);
10908 mLastIdleTimeStart = elapsedRealtimeMillis;
10909 mLongestLightIdleTime = 0;
10910 mLongestFullIdleTime = 0;
10911 mDeviceIdleModeLightTimer.reset(false);
10912 mDeviceIdleModeFullTimer.reset(false);
10913 mDeviceLightIdlingTimer.reset(false);
10914 mDeviceIdlingTimer.reset(false);
10915 mPhoneOnTimer.reset(false);
10916 mAudioOnTimer.reset(false);
10917 mVideoOnTimer.reset(false);
10918 mFlashlightOnTimer.reset(false);
10919 mCameraOnTimer.reset(false);
10920 mBluetoothScanTimer.reset(false);
10921 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
10922 mPhoneSignalStrengthsTimer[i].reset(false);
10924 mPhoneSignalScanningTimer.reset(false);
10925 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
10926 mPhoneDataConnectionsTimer[i].reset(false);
10928 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
10929 mNetworkByteActivityCounters[i].reset(false);
10930 mNetworkPacketActivityCounters[i].reset(false);
10932 mMobileRadioActiveTimer.reset(false);
10933 mMobileRadioActivePerAppTimer.reset(false);
10934 mMobileRadioActiveAdjustedTime.reset(false);
10935 mMobileRadioActiveUnknownTime.reset(false);
10936 mMobileRadioActiveUnknownCount.reset(false);
10937 mWifiOnTimer.reset(false);
10938 mGlobalWifiRunningTimer.reset(false);
10939 for (int i=0; i<NUM_WIFI_STATES; i++) {
10940 mWifiStateTimer[i].reset(false);
10942 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
10943 mWifiSupplStateTimer[i].reset(false);
10945 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
10946 mWifiSignalStrengthsTimer[i].reset(false);
10948 mWifiMulticastWakelockTimer.reset(false);
10949 mWifiActiveTimer.reset(false);
10950 mWifiActivity.reset(false);
10951 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
10952 mGpsSignalQualityTimer[i].reset(false);
10954 mBluetoothActivity.reset(false);
10955 mModemActivity.reset(false);
10956 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
10958 for (int i=0; i<mUidStats.size(); i++) {
10959 if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) {
10960 mUidStats.remove(mUidStats.keyAt(i));
10965 if (mRpmStats.size() > 0) {
10966 for (SamplingTimer timer : mRpmStats.values()) {
10967 mOnBatteryTimeBase.remove(timer);
10971 if (mScreenOffRpmStats.size() > 0) {
10972 for (SamplingTimer timer : mScreenOffRpmStats.values()) {
10973 mOnBatteryScreenOffTimeBase.remove(timer);
10975 mScreenOffRpmStats.clear();
10978 if (mKernelWakelockStats.size() > 0) {
10979 for (SamplingTimer timer : mKernelWakelockStats.values()) {
10980 mOnBatteryScreenOffTimeBase.remove(timer);
10982 mKernelWakelockStats.clear();
10985 if (mKernelMemoryStats.size() > 0) {
10986 for (int i = 0; i < mKernelMemoryStats.size(); i++) {
10987 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i));
10989 mKernelMemoryStats.clear();
10992 if (mWakeupReasonStats.size() > 0) {
10993 for (SamplingTimer timer : mWakeupReasonStats.values()) {
10994 mOnBatteryTimeBase.remove(timer);
10996 mWakeupReasonStats.clear();
10999 mLastHistoryStepDetails = null;
11000 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0;
11001 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0;
11002 mLastStepCpuUserTime = mCurStepCpuUserTime = 0;
11003 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0;
11004 mLastStepStatUserTime = mCurStepStatUserTime = 0;
11005 mLastStepStatSystemTime = mCurStepStatSystemTime = 0;
11006 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0;
11007 mLastStepStatIrqTime = mCurStepStatIrqTime = 0;
11008 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0;
11009 mLastStepStatIdleTime = mCurStepStatIdleTime = 0;
11013 clearHistoryLocked();
11016 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
11017 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
11018 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) {
11019 // Not recording process starts/stops.
11022 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
11023 if (active == null) {
11026 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
11027 SparseIntArray uids = ent.getValue();
11028 for (int j=0; j<uids.size(); j++) {
11029 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
11036 void updateDischargeScreenLevelsLocked(int oldState, int newState) {
11037 updateOldDischargeScreenLevelLocked(oldState);
11038 updateNewDischargeScreenLevelLocked(newState);
11041 private void updateOldDischargeScreenLevelLocked(int state) {
11042 if (isScreenOn(state)) {
11043 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
11045 mDischargeAmountScreenOn += diff;
11046 mDischargeAmountScreenOnSinceCharge += diff;
11048 } else if (isScreenDoze(state)) {
11049 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel;
11051 mDischargeAmountScreenDoze += diff;
11052 mDischargeAmountScreenDozeSinceCharge += diff;
11054 } else if (isScreenOff(state)){
11055 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
11057 mDischargeAmountScreenOff += diff;
11058 mDischargeAmountScreenOffSinceCharge += diff;
11063 private void updateNewDischargeScreenLevelLocked(int state) {
11064 if (isScreenOn(state)) {
11065 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
11066 mDischargeScreenOffUnplugLevel = 0;
11067 mDischargeScreenDozeUnplugLevel = 0;
11068 } else if (isScreenDoze(state)){
11069 mDischargeScreenOnUnplugLevel = 0;
11070 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel;
11071 mDischargeScreenOffUnplugLevel = 0;
11072 } else if (isScreenOff(state)) {
11073 mDischargeScreenOnUnplugLevel = 0;
11074 mDischargeScreenDozeUnplugLevel = 0;
11075 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
11079 public void pullPendingStateUpdatesLocked() {
11080 if (mOnBatteryInternal) {
11081 updateDischargeScreenLevelsLocked(mScreenState, mScreenState);
11085 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
11086 private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6);
11088 private final Object mWifiNetworkLock = new Object();
11090 @GuardedBy("mWifiNetworkLock")
11091 private String[] mWifiIfaces = EmptyArray.STRING;
11093 @GuardedBy("mWifiNetworkLock")
11094 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1);
11096 private final Object mModemNetworkLock = new Object();
11098 @GuardedBy("mModemNetworkLock")
11099 private String[] mModemIfaces = EmptyArray.STRING;
11101 @GuardedBy("mModemNetworkLock")
11102 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1);
11104 private NetworkStats readNetworkStatsLocked(String[] ifaces) {
11106 if (!ArrayUtils.isEmpty(ifaces)) {
11107 return mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces,
11108 NetworkStats.TAG_NONE, mNetworkStatsPool.acquire());
11110 } catch (IOException e) {
11111 Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces));
11117 * Distribute WiFi energy info and network traffic to apps.
11118 * @param info The energy information from the WiFi controller.
11120 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) {
11121 if (DEBUG_ENERGY) {
11122 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces));
11125 // Grab a separate lock to acquire the network stats, which may do I/O.
11126 NetworkStats delta = null;
11127 synchronized (mWifiNetworkLock) {
11128 final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces);
11129 if (latestStats != null) {
11130 delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null,
11131 mNetworkStatsPool.acquire());
11132 mNetworkStatsPool.release(mLastWifiNetworkStats);
11133 mLastWifiNetworkStats = latestStats;
11137 synchronized (this) {
11138 if (!mOnBatteryInternal) {
11139 if (delta != null) {
11140 mNetworkStatsPool.release(delta);
11145 final long elapsedRealtimeMs = mClocks.elapsedRealtime();
11146 SparseLongArray rxPackets = new SparseLongArray();
11147 SparseLongArray txPackets = new SparseLongArray();
11148 long totalTxPackets = 0;
11149 long totalRxPackets = 0;
11150 if (delta != null) {
11151 NetworkStats.Entry entry = new NetworkStats.Entry();
11152 final int size = delta.size();
11153 for (int i = 0; i < size; i++) {
11154 entry = delta.getValues(i, entry);
11156 if (DEBUG_ENERGY) {
11157 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
11158 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
11159 + " txPackets=" + entry.txPackets);
11162 if (entry.rxBytes == 0 && entry.txBytes == 0) {
11163 // Skip the lookup below since there is no work to do.
11167 final Uid u = getUidStatsLocked(mapUid(entry.uid));
11168 if (entry.rxBytes != 0) {
11169 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
11171 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
11172 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes,
11175 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
11177 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
11180 rxPackets.put(u.getUid(), entry.rxPackets);
11182 // Sum the total number of packets so that the Rx Power can
11183 // be evenly distributed amongst the apps.
11184 totalRxPackets += entry.rxPackets;
11187 if (entry.txBytes != 0) {
11188 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
11190 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
11191 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes,
11194 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
11196 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
11199 txPackets.put(u.getUid(), entry.txPackets);
11201 // Sum the total number of packets so that the Tx Power can
11202 // be evenly distributed amongst the apps.
11203 totalTxPackets += entry.txPackets;
11206 mNetworkStatsPool.release(delta);
11210 if (info != null) {
11211 mHasWifiReporting = true;
11213 // Measured in mAms
11214 final long txTimeMs = info.getControllerTxTimeMillis();
11215 final long rxTimeMs = info.getControllerRxTimeMillis();
11216 final long scanTimeMs = info.getControllerScanTimeMillis();
11217 final long idleTimeMs = info.getControllerIdleTimeMillis();
11218 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
11220 long leftOverRxTimeMs = rxTimeMs;
11221 long leftOverTxTimeMs = txTimeMs;
11223 if (DEBUG_ENERGY) {
11224 Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
11225 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
11226 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
11227 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
11228 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms");
11229 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms");
11232 long totalWifiLockTimeMs = 0;
11233 long totalScanTimeMs = 0;
11235 // On the first pass, collect some totals so that we can normalize power
11236 // calculations if we need to.
11237 final int uidStatsSize = mUidStats.size();
11238 for (int i = 0; i < uidStatsSize; i++) {
11239 final Uid uid = mUidStats.valueAt(i);
11241 // Sum the total scan power for all apps.
11242 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
11243 elapsedRealtimeMs * 1000) / 1000;
11245 // Sum the total time holding wifi lock for all apps.
11246 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
11247 elapsedRealtimeMs * 1000) / 1000;
11250 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
11252 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
11253 + rxTimeMs + " ms). Normalizing scan time.");
11255 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) {
11257 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > "
11258 + txTimeMs + " ms). Normalizing scan time.");
11261 // Actually assign and distribute power usage to apps.
11262 for (int i = 0; i < uidStatsSize; i++) {
11263 final Uid uid = mUidStats.valueAt(i);
11265 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
11266 elapsedRealtimeMs * 1000) / 1000;
11267 if (scanTimeSinceMarkMs > 0) {
11268 // Set the new mark so that next time we get new data since this point.
11269 uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
11271 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs;
11272 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs;
11274 // Our total scan time is more than the reported Tx/Rx time.
11275 // This is possible because the cost of a scan is approximate.
11276 // Let's normalize the result so that we evenly blame each app
11279 // This means that we may have apps that transmitted/received packets not be
11280 // blamed for this, but this is fine as scans are relatively more expensive.
11281 if (totalScanTimeMs > rxTimeMs) {
11282 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) /
11285 if (totalScanTimeMs > txTimeMs) {
11286 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) /
11290 if (DEBUG_ENERGY) {
11291 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:"
11292 + scanRxTimeSinceMarkMs + " ms Tx:"
11293 + scanTxTimeSinceMarkMs + " ms)");
11296 ControllerActivityCounterImpl activityCounter =
11297 uid.getOrCreateWifiControllerActivityLocked();
11298 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs);
11299 activityCounter.getTxTimeCounters()[0].addCountLocked(
11300 scanTxTimeSinceMarkMs);
11301 leftOverRxTimeMs -= scanRxTimeSinceMarkMs;
11302 leftOverTxTimeMs -= scanTxTimeSinceMarkMs;
11305 // Distribute evenly the power consumed while Idle to each app holding a WiFi
11307 final long wifiLockTimeSinceMarkMs =
11308 uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
11309 elapsedRealtimeMs * 1000) / 1000;
11310 if (wifiLockTimeSinceMarkMs > 0) {
11311 // Set the new mark so that next time we get new data since this point.
11312 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
11314 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
11315 / totalWifiLockTimeMs;
11316 if (DEBUG_ENERGY) {
11317 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": "
11318 + myIdleTimeMs + " ms");
11320 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter()
11321 .addCountLocked(myIdleTimeMs);
11325 if (DEBUG_ENERGY) {
11326 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
11327 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms");
11330 // Distribute the remaining Tx power appropriately between all apps that transmitted
11332 for (int i = 0; i < txPackets.size(); i++) {
11333 final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
11334 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs)
11336 if (DEBUG_ENERGY) {
11337 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
11339 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0]
11340 .addCountLocked(myTxTimeMs);
11343 // Distribute the remaining Rx power appropriately between all apps that received
11345 for (int i = 0; i < rxPackets.size(); i++) {
11346 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i));
11347 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs)
11349 if (DEBUG_ENERGY) {
11350 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
11352 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter()
11353 .addCountLocked(myRxTimeMs);
11356 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
11359 // Update WiFi controller stats.
11360 mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis());
11361 mWifiActivity.getTxTimeCounters()[0].addCountLocked(
11362 info.getControllerTxTimeMillis());
11363 mWifiActivity.getScanTimeCounter().addCountLocked(
11364 info.getControllerScanTimeMillis());
11365 mWifiActivity.getIdleTimeCounter().addCountLocked(
11366 info.getControllerIdleTimeMillis());
11368 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
11369 final double opVolt = mPowerProfile.getAveragePower(
11370 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
11372 // We store the power drain as mAms.
11373 mWifiActivity.getPowerCounter().addCountLocked(
11374 (long) (info.getControllerEnergyUsed() / opVolt));
11380 private ModemActivityInfo mLastModemActivityInfo =
11381 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
11383 private ModemActivityInfo getDeltaModemActivityInfo(ModemActivityInfo activityInfo) {
11384 if (activityInfo == null) {
11387 int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
11388 for (int i = 0; i < ModemActivityInfo.TX_POWER_LEVELS; i++) {
11389 txTimeMs[i] = activityInfo.getTxTimeMillis()[i]
11390 - mLastModemActivityInfo.getTxTimeMillis()[i];
11392 ModemActivityInfo deltaInfo = new ModemActivityInfo(activityInfo.getTimestamp(),
11393 activityInfo.getSleepTimeMillis() - mLastModemActivityInfo.getSleepTimeMillis(),
11394 activityInfo.getIdleTimeMillis() - mLastModemActivityInfo.getIdleTimeMillis(),
11396 activityInfo.getRxTimeMillis() - mLastModemActivityInfo.getRxTimeMillis(),
11397 activityInfo.getEnergyUsed() - mLastModemActivityInfo.getEnergyUsed());
11398 mLastModemActivityInfo = activityInfo;
11403 * Distribute Cell radio energy info and network traffic to apps.
11405 public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) {
11406 if (DEBUG_ENERGY) {
11407 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo);
11409 ModemActivityInfo deltaInfo = getDeltaModemActivityInfo(activityInfo);
11411 // Add modem tx power to history.
11412 addModemTxPowerToHistory(deltaInfo);
11414 // Grab a separate lock to acquire the network stats, which may do I/O.
11415 NetworkStats delta = null;
11416 synchronized (mModemNetworkLock) {
11417 final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces);
11418 if (latestStats != null) {
11419 delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null,
11420 mNetworkStatsPool.acquire());
11421 mNetworkStatsPool.release(mLastModemNetworkStats);
11422 mLastModemNetworkStats = latestStats;
11426 synchronized (this) {
11427 if (!mOnBatteryInternal) {
11428 if (delta != null) {
11429 mNetworkStatsPool.release(delta);
11434 if (deltaInfo != null) {
11435 mHasModemReporting = true;
11436 mModemActivity.getIdleTimeCounter().addCountLocked(
11437 deltaInfo.getIdleTimeMillis());
11438 mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getRxTimeMillis());
11439 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
11440 mModemActivity.getTxTimeCounters()[lvl]
11441 .addCountLocked(deltaInfo.getTxTimeMillis()[lvl]);
11444 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
11445 final double opVolt = mPowerProfile.getAveragePower(
11446 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
11448 double energyUsed =
11449 deltaInfo.getSleepTimeMillis() *
11450 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP)
11451 + deltaInfo.getIdleTimeMillis() *
11452 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE)
11453 + deltaInfo.getRxTimeMillis() *
11454 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX);
11455 int[] txTimeMs = deltaInfo.getTxTimeMillis();
11456 for (int i = 0; i < Math.min(txTimeMs.length,
11457 SignalStrength.NUM_SIGNAL_STRENGTH_BINS); i++) {
11458 energyUsed += txTimeMs[i] * mPowerProfile.getAveragePower(
11459 PowerProfile.POWER_MODEM_CONTROLLER_TX, i);
11462 // We store the power drain as mAms.
11463 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed);
11467 final long elapsedRealtimeMs = mClocks.elapsedRealtime();
11468 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
11469 elapsedRealtimeMs * 1000);
11470 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
11472 long totalRxPackets = 0;
11473 long totalTxPackets = 0;
11474 if (delta != null) {
11475 NetworkStats.Entry entry = new NetworkStats.Entry();
11476 final int size = delta.size();
11477 for (int i = 0; i < size; i++) {
11478 entry = delta.getValues(i, entry);
11479 if (entry.rxPackets == 0 && entry.txPackets == 0) {
11483 if (DEBUG_ENERGY) {
11484 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
11485 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
11486 + " txPackets=" + entry.txPackets);
11489 totalRxPackets += entry.rxPackets;
11490 totalTxPackets += entry.txPackets;
11492 final Uid u = getUidStatsLocked(mapUid(entry.uid));
11493 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
11495 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
11497 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
11498 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA,
11499 entry.rxBytes, entry.rxPackets);
11500 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA,
11501 entry.txBytes, entry.txPackets);
11504 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
11506 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
11508 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
11510 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
11514 // Now distribute proportional blame to the apps that did networking.
11515 long totalPackets = totalRxPackets + totalTxPackets;
11516 if (totalPackets > 0) {
11517 for (int i = 0; i < size; i++) {
11518 entry = delta.getValues(i, entry);
11519 if (entry.rxPackets == 0 && entry.txPackets == 0) {
11523 final Uid u = getUidStatsLocked(mapUid(entry.uid));
11525 // Distribute total radio active time in to this app.
11526 final long appPackets = entry.rxPackets + entry.txPackets;
11527 final long appRadioTime = (radioTime * appPackets) / totalPackets;
11528 u.noteMobileRadioActiveTimeLocked(appRadioTime);
11530 // Remove this app from the totals, so that we don't lose any time
11531 // due to rounding.
11532 radioTime -= appRadioTime;
11533 totalPackets -= appPackets;
11535 if (deltaInfo != null) {
11536 ControllerActivityCounterImpl activityCounter =
11537 u.getOrCreateModemControllerActivityLocked();
11538 if (totalRxPackets > 0 && entry.rxPackets > 0) {
11539 final long rxMs = (entry.rxPackets * deltaInfo.getRxTimeMillis())
11541 activityCounter.getRxTimeCounter().addCountLocked(rxMs);
11544 if (totalTxPackets > 0 && entry.txPackets > 0) {
11545 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
11547 entry.txPackets * deltaInfo.getTxTimeMillis()[lvl];
11548 txMs /= totalTxPackets;
11549 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs);
11556 if (radioTime > 0) {
11557 // Whoops, there is some radio time we can't blame on an app!
11558 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
11559 mMobileRadioActiveUnknownCount.addCountLocked(1);
11562 mNetworkStatsPool.release(delta);
11568 // Cache last value for comparison.
11569 private BluetoothActivityEnergyInfo mLastBluetoothActivityEnergyInfo =
11570 new BluetoothActivityEnergyInfo(0, 0, 0, 0, 0, 0);
11573 * Add modem tx power to history
11574 * Device is said to be in high cellular transmit power when it has spent most of the transmit
11575 * time at the highest power level.
11576 * @param activityInfo
11578 private void addModemTxPowerToHistory(final ModemActivityInfo activityInfo) {
11579 if (activityInfo == null) {
11582 int[] txTimeMs = activityInfo.getTxTimeMillis();
11583 if (txTimeMs == null || txTimeMs.length != ModemActivityInfo.TX_POWER_LEVELS) {
11586 final long elapsedRealtime = mClocks.elapsedRealtime();
11587 final long uptime = mClocks.uptimeMillis();
11588 int levelMaxTimeSpent = 0;
11589 for (int i = 1; i < txTimeMs.length; i++) {
11590 if (txTimeMs[i] > txTimeMs[levelMaxTimeSpent]) {
11591 levelMaxTimeSpent = i;
11594 if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) {
11595 if (!mIsCellularTxPowerHigh) {
11596 mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
11597 addHistoryRecordLocked(elapsedRealtime, uptime);
11598 mIsCellularTxPowerHigh = true;
11602 if (mIsCellularTxPowerHigh) {
11603 mHistoryCur.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
11604 addHistoryRecordLocked(elapsedRealtime, uptime);
11605 mIsCellularTxPowerHigh = false;
11611 * Distribute Bluetooth energy info and network traffic to apps.
11612 * @param info The energy information from the bluetooth controller.
11614 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
11615 if (DEBUG_ENERGY) {
11616 Slog.d(TAG, "Updating bluetooth stats: " + info);
11619 if (info == null || !mOnBatteryInternal) {
11623 mHasBluetoothReporting = true;
11625 final long elapsedRealtimeMs = mClocks.elapsedRealtime();
11626 final long rxTimeMs = info.getControllerRxTimeMillis() -
11627 mLastBluetoothActivityEnergyInfo.getControllerRxTimeMillis();
11628 final long txTimeMs = info.getControllerTxTimeMillis() -
11629 mLastBluetoothActivityEnergyInfo.getControllerTxTimeMillis();
11630 final long idleTimeMs = info.getControllerIdleTimeMillis() -
11631 mLastBluetoothActivityEnergyInfo.getControllerIdleTimeMillis();
11632 if (DEBUG_ENERGY) {
11633 Slog.d(TAG, "------ BEGIN BLE power blaming ------");
11634 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
11635 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
11636 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
11639 long totalScanTimeMs = 0;
11641 final int uidCount = mUidStats.size();
11642 for (int i = 0; i < uidCount; i++) {
11643 final Uid u = mUidStats.valueAt(i);
11644 if (u.mBluetoothScanTimer == null) {
11648 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked(
11649 elapsedRealtimeMs * 1000) / 1000;
11652 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs);
11653 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs);
11655 if (DEBUG_ENERGY) {
11656 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime
11657 + " TX=" + normalizeScanTxTime);
11660 long leftOverRxTimeMs = rxTimeMs;
11661 long leftOverTxTimeMs = txTimeMs;
11663 for (int i = 0; i < uidCount; i++) {
11664 final Uid u = mUidStats.valueAt(i);
11665 if (u.mBluetoothScanTimer == null) {
11669 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked(
11670 elapsedRealtimeMs * 1000) / 1000;
11671 if (scanTimeSinceMarkMs > 0) {
11672 // Set the new mark so that next time we get new data since this point.
11673 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs);
11675 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs;
11676 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs;
11678 if (normalizeScanRxTime) {
11679 // Scan time is longer than the total rx time in the controller,
11680 // so distribute the scan time proportionately. This means regular traffic
11681 // will not blamed, but scans are more expensive anyways.
11682 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs;
11685 if (normalizeScanTxTime) {
11686 // Scan time is longer than the total tx time in the controller,
11687 // so distribute the scan time proportionately. This means regular traffic
11688 // will not blamed, but scans are more expensive anyways.
11689 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs;
11692 final ControllerActivityCounterImpl counter =
11693 u.getOrCreateBluetoothControllerActivityLocked();
11694 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs);
11695 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs);
11697 leftOverRxTimeMs -= scanTimeRxSinceMarkMs;
11698 leftOverTxTimeMs -= scanTimeTxSinceMarkMs;
11702 if (DEBUG_ENERGY) {
11703 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs
11704 + " TX=" + leftOverTxTimeMs);
11708 // Now distribute blame to apps that did bluetooth traffic.
11711 long totalTxBytes = 0;
11712 long totalRxBytes = 0;
11714 final UidTraffic[] uidTraffic = info.getUidTraffic();
11715 final UidTraffic[] lastUidTraffic = mLastBluetoothActivityEnergyInfo.getUidTraffic();
11716 final ArrayList<UidTraffic> deltaTraffic = new ArrayList<>();
11718 for (; m < uidTraffic.length && n < lastUidTraffic.length; m++) {
11719 final UidTraffic traffic = uidTraffic[m];
11720 final UidTraffic lastTraffic = lastUidTraffic[n];
11721 if (traffic.getUid() == lastTraffic.getUid()) {
11722 deltaTraffic.add(new UidTraffic(traffic.getUid(),
11723 traffic.getRxBytes() - lastTraffic.getRxBytes(),
11724 traffic.getTxBytes() - lastTraffic.getTxBytes()));
11728 for (; m < uidTraffic.length; m ++) {
11729 deltaTraffic.add(uidTraffic[m]);
11732 for (int i = 0, j = 0; i < deltaTraffic.size(); i++) {
11733 final UidTraffic traffic = deltaTraffic.get(i);
11735 // Add to the global counters.
11736 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(
11737 traffic.getRxBytes());
11738 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(
11739 traffic.getTxBytes());
11741 // Add to the UID counters.
11742 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()));
11743 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, traffic.getRxBytes(), 0);
11744 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, traffic.getTxBytes(), 0);
11746 // Calculate the total traffic.
11747 totalTxBytes += traffic.getTxBytes();
11748 totalRxBytes += traffic.getRxBytes();
11751 if ((totalTxBytes != 0 || totalRxBytes != 0) &&
11752 (leftOverRxTimeMs != 0 || leftOverTxTimeMs != 0)) {
11753 for (int i = 0; i < deltaTraffic.size(); i++) {
11754 final UidTraffic traffic = deltaTraffic.get(i);
11756 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()));
11757 final ControllerActivityCounterImpl counter =
11758 u.getOrCreateBluetoothControllerActivityLocked();
11760 if (totalRxBytes > 0 && traffic.getRxBytes() > 0) {
11761 final long timeRxMs = (leftOverRxTimeMs * traffic.getRxBytes()) / totalRxBytes;
11763 if (DEBUG_ENERGY) {
11764 Slog.d(TAG, "UID=" + traffic.getUid() + " rx_bytes=" + traffic.getRxBytes()
11765 + " rx_time=" + timeRxMs);
11767 counter.getRxTimeCounter().addCountLocked(timeRxMs);
11768 leftOverRxTimeMs -= timeRxMs;
11771 if (totalTxBytes > 0 && traffic.getTxBytes() > 0) {
11772 final long timeTxMs = (leftOverTxTimeMs * traffic.getTxBytes()) / totalTxBytes;
11774 if (DEBUG_ENERGY) {
11775 Slog.d(TAG, "UID=" + traffic.getUid() + " tx_bytes=" + traffic.getTxBytes()
11776 + " tx_time=" + timeTxMs);
11779 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs);
11780 leftOverTxTimeMs -= timeTxMs;
11785 mBluetoothActivity.getRxTimeCounter().addCountLocked(rxTimeMs);
11786 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(txTimeMs);
11787 mBluetoothActivity.getIdleTimeCounter().addCountLocked(idleTimeMs);
11789 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
11790 final double opVolt = mPowerProfile.getAveragePower(
11791 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
11793 // We store the power drain as mAms.
11794 mBluetoothActivity.getPowerCounter().addCountLocked(
11795 (long) ((info.getControllerEnergyUsed() -
11796 mLastBluetoothActivityEnergyInfo.getControllerEnergyUsed() )/ opVolt));
11798 mLastBluetoothActivityEnergyInfo = info;
11802 * Read and record Resource Power Manager (RPM) state and voter times.
11803 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data
11804 * instead of fetching it anew.
11806 public void updateRpmStatsLocked() {
11807 if (mPlatformIdleStateCallback == null) return;
11808 long now = SystemClock.elapsedRealtime();
11809 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) {
11810 mPlatformIdleStateCallback.fillLowPowerStats(mTmpRpmStats);
11811 mLastRpmStatsUpdateTimeMs = now;
11814 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate
11815 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) {
11817 // Update values for this platform state.
11818 final String pName = pstate.getKey();
11819 final long pTimeUs = pstate.getValue().mTimeMs * 1000;
11820 final int pCount = pstate.getValue().mCount;
11821 getRpmTimerLocked(pName).update(pTimeUs, pCount);
11822 if (SCREEN_OFF_RPM_STATS_ENABLED) {
11823 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount);
11826 // Update values for each voter of this platform state.
11827 for (Map.Entry<String, RpmStats.PowerStateElement> voter
11828 : pstate.getValue().mVoters.entrySet()) {
11829 final String vName = pName + "." + voter.getKey();
11830 final long vTimeUs = voter.getValue().mTimeMs * 1000;
11831 final int vCount = voter.getValue().mCount;
11832 getRpmTimerLocked(vName).update(vTimeUs, vCount);
11833 if (SCREEN_OFF_RPM_STATS_ENABLED) {
11834 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount);
11839 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys
11840 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) {
11842 final String subsysName = subsys.getKey();
11843 for (Map.Entry<String, RpmStats.PowerStateElement> sstate
11844 : subsys.getValue().mStates.entrySet()) {
11845 final String name = subsysName + "." + sstate.getKey();
11846 final long timeUs = sstate.getValue().mTimeMs * 1000;
11847 final int count = sstate.getValue().mCount;
11848 getRpmTimerLocked(name).update(timeUs, count);
11849 if (SCREEN_OFF_RPM_STATS_ENABLED) {
11850 getScreenOffRpmTimerLocked(name).update(timeUs, count);
11857 * Read and distribute kernel wake lock use across apps.
11859 public void updateKernelWakelocksLocked() {
11860 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
11861 mTmpWakelockStats);
11862 if (wakelockStats == null) {
11863 // Not crashing might make board bringup easier.
11864 Slog.w(TAG, "Couldn't get kernel wake lock stats");
11868 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
11869 String name = ent.getKey();
11870 KernelWakelockStats.Entry kws = ent.getValue();
11872 SamplingTimer kwlt = mKernelWakelockStats.get(name);
11873 if (kwlt == null) {
11874 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase);
11875 mKernelWakelockStats.put(name, kwlt);
11878 kwlt.update(kws.mTotalTime, kws.mCount);
11879 kwlt.setUpdateVersion(kws.mVersion);
11882 int numWakelocksSetStale = 0;
11883 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks)
11885 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
11886 SamplingTimer st = ent.getValue();
11887 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
11889 numWakelocksSetStale++;
11893 // Record whether we've seen a non-zero time (for debugging b/22716723).
11894 if (wakelockStats.isEmpty()) {
11895 Slog.wtf(TAG, "All kernel wakelocks had time of zero");
11898 if (numWakelocksSetStale == mKernelWakelockStats.size()) {
11899 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" +
11900 wakelockStats.kernelWakelockVersion);
11904 // We use an anonymous class to access these variables,
11905 // so they can't live on the stack or they'd have to be
11906 // final MutableLong objects (more allocations).
11907 // Used in updateCpuTimeLocked().
11908 long mTempTotalCpuUserTimeUs;
11909 long mTempTotalCpuSystemTimeUs;
11910 long[][] mWakeLockAllocationsUs;
11913 * Reads the newest memory stats from the kernel.
11915 public void updateKernelMemoryBandwidthLocked() {
11916 mKernelMemoryBandwidthStats.updateStats();
11917 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries();
11918 final int bandwidthEntryCount = bandwidthEntries.size();
11920 for (int i = 0; i < bandwidthEntryCount; i++) {
11921 SamplingTimer timer;
11922 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) {
11923 timer = mKernelMemoryStats.valueAt(index);
11925 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase);
11926 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer);
11928 timer.update(bandwidthEntries.valueAt(i), 1);
11929 if (DEBUG_MEMORY) {
11930 Slog.d(TAG, String.format("Added entry %d and updated timer to: "
11931 + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i),
11932 mKernelMemoryStats.get(
11933 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime,
11934 mKernelMemoryStats.size()));
11939 public boolean isOnBatteryLocked() {
11940 return mOnBatteryTimeBase.isRunning();
11943 public boolean isOnBatteryScreenOffLocked() {
11944 return mOnBatteryScreenOffTimeBase.isRunning();
11948 * Read and distribute CPU usage across apps. If their are partial wakelocks being held
11949 * and we are on battery with screen off, we give more of the cpu time to those apps holding
11950 * wakelocks. If the screen is on, we just assign the actual cpu time an app used.
11951 * It's possible this will be invoked after the internal battery/screen states are updated, so
11952 * passing the appropriate battery/screen states to try attribute the cpu times to correct
11956 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff) {
11957 if (mPowerProfile == null) {
11961 if (DEBUG_ENERGY_CPU) {
11962 Slog.d(TAG, "!Cpu updating!");
11965 if (mCpuFreqs == null) {
11966 mCpuFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile);
11969 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is
11970 // usually holding the wakelock on behalf of an app.
11971 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery.
11972 ArrayList<StopwatchTimer> partialTimersToConsider = null;
11973 if (onBatteryScreenOff) {
11974 partialTimersToConsider = new ArrayList<>();
11975 for (int i = mPartialTimers.size() - 1; i >= 0; --i) {
11976 final StopwatchTimer timer = mPartialTimers.get(i);
11977 // Since the collection and blaming of wakelocks can be scheduled to run after
11978 // some delay, the mPartialTimers list may have new entries. We can't blame
11979 // the newly added timer for past cpu time, so we only consider timers that
11980 // were present for one round of collection. Once a timer has gone through
11981 // a round of collection, its mInList field is set to true.
11982 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
11983 partialTimersToConsider.add(timer);
11987 markPartialTimersAsEligible();
11989 // When the battery is not on, we don't attribute the cpu times to any timers but we still
11990 // need to take the snapshots.
11992 mKernelUidCpuTimeReader.readDelta(null);
11993 mKernelUidCpuFreqTimeReader.readDelta(null);
11994 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
11995 mKernelUidCpuActiveTimeReader.readDelta(null);
11996 mKernelUidCpuClusterTimeReader.readDelta(null);
11998 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) {
11999 mKernelCpuSpeedReaders[cluster].readDelta();
12004 mUserInfoProvider.refreshUserIds();
12005 final SparseLongArray updatedUids = mKernelUidCpuFreqTimeReader.perClusterTimesAvailable()
12006 ? null : new SparseLongArray();
12007 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery);
12008 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu
12009 // freqs, so no need to approximate these values.
12010 if (updatedUids != null) {
12011 updateClusterSpeedTimes(updatedUids, onBattery);
12013 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff);
12014 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
12015 readKernelUidCpuActiveTimesLocked(onBattery);
12016 readKernelUidCpuClusterTimesLocked(onBattery);
12021 * Mark the current partial timers as gone through a collection so that they will be
12022 * considered in the next cpu times distribution to wakelock holders.
12025 public void markPartialTimersAsEligible() {
12026 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) {
12027 // No difference, so each timer is now considered for the next collection.
12028 for (int i = mPartialTimers.size() - 1; i >= 0; --i) {
12029 mPartialTimers.get(i).mInList = true;
12032 // The lists are different, meaning we added (or removed a timer) since the last
12034 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) {
12035 mLastPartialTimers.get(i).mInList = false;
12037 mLastPartialTimers.clear();
12039 // Mark the current timers as gone through a collection.
12040 final int numPartialTimers = mPartialTimers.size();
12041 for (int i = 0; i < numPartialTimers; ++i) {
12042 final StopwatchTimer timer = mPartialTimers.get(i);
12043 timer.mInList = true;
12044 mLastPartialTimers.add(timer);
12050 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and
12051 * calculate cpu times spent by each uid at different frequencies.
12053 * @param updatedUids The uids for which times spent at different frequencies are calculated.
12056 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery) {
12057 long totalCpuClustersTimeMs = 0;
12058 // Read the time spent for each cluster at various cpu frequencies.
12059 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][];
12060 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
12061 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta();
12062 if (clusterSpeedTimesMs[cluster] != null) {
12063 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) {
12064 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed];
12068 if (totalCpuClustersTimeMs != 0) {
12069 // We have cpu times per freq aggregated over all uids but we need the times per uid.
12070 // So, we distribute total time spent by an uid to different cpu freqs based on the
12071 // amount of time cpu was running at that freq.
12072 final int updatedUidsCount = updatedUids.size();
12073 for (int i = 0; i < updatedUidsCount; ++i) {
12074 final Uid u = getUidStatsLocked(updatedUids.keyAt(i));
12075 final long appCpuTimeUs = updatedUids.valueAt(i);
12076 // Add the cpu speeds to this UID.
12077 final int numClusters = mPowerProfile.getNumCpuClusters();
12078 if (u.mCpuClusterSpeedTimesUs == null ||
12079 u.mCpuClusterSpeedTimesUs.length != numClusters) {
12080 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
12083 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) {
12084 final int speedsInCluster = clusterSpeedTimesMs[cluster].length;
12085 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster !=
12086 u.mCpuClusterSpeedTimesUs[cluster].length) {
12087 u.mCpuClusterSpeedTimesUs[cluster]
12088 = new LongSamplingCounter[speedsInCluster];
12091 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster];
12092 for (int speed = 0; speed < speedsInCluster; speed++) {
12093 if (cpuSpeeds[speed] == null) {
12094 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
12096 cpuSpeeds[speed].addCountLocked(appCpuTimeUs
12097 * clusterSpeedTimesMs[cluster][speed]
12098 / totalCpuClustersTimeMs, onBattery);
12106 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters.
12107 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to
12108 * wakelock holders.
12110 * @param partialTimers The wakelock holders among which the cpu times will be distributed.
12111 * @param updatedUids If not null, then the uids found in the snapshot will be added to this.
12114 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers,
12115 @Nullable SparseLongArray updatedUids, boolean onBattery) {
12116 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0;
12117 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size();
12118 final long startTimeMs = mClocks.uptimeMillis();
12120 mKernelUidCpuTimeReader.readDelta((uid, userTimeUs, systemTimeUs) -> {
12122 if (Process.isIsolated(uid)) {
12123 // This could happen if the isolated uid mapping was removed before that process
12124 // was actually killed.
12125 mKernelUidCpuTimeReader.removeUid(uid);
12126 Slog.d(TAG, "Got readings for an isolated uid with no mapping: " + uid);
12129 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
12130 Slog.d(TAG, "Got readings for an invalid user's uid " + uid);
12131 mKernelUidCpuTimeReader.removeUid(uid);
12134 final Uid u = getUidStatsLocked(uid);
12136 // Accumulate the total system and user time.
12137 mTempTotalCpuUserTimeUs += userTimeUs;
12138 mTempTotalCpuSystemTimeUs += systemTimeUs;
12140 StringBuilder sb = null;
12141 if (DEBUG_ENERGY_CPU) {
12142 sb = new StringBuilder();
12143 sb.append(" got time for uid=").append(u.mUid).append(": u=");
12144 TimeUtils.formatDuration(userTimeUs / 1000, sb);
12146 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
12150 if (numWakelocks > 0) {
12151 // We have wakelocks being held, so only give a portion of the
12152 // time to the process. The rest will be distributed among wakelock
12154 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100;
12155 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100;
12159 sb.append(" adding to uid=").append(u.mUid).append(": u=");
12160 TimeUtils.formatDuration(userTimeUs / 1000, sb);
12162 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
12163 Slog.d(TAG, sb.toString());
12166 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery);
12167 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery);
12168 if (updatedUids != null) {
12169 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs);
12173 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
12174 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
12175 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms");
12178 if (numWakelocks > 0) {
12179 // Distribute a portion of the total cpu time to wakelock holders.
12180 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100;
12181 mTempTotalCpuSystemTimeUs =
12182 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100;
12184 for (int i = 0; i < numWakelocks; ++i) {
12185 final StopwatchTimer timer = partialTimers.get(i);
12186 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i));
12187 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i));
12189 if (DEBUG_ENERGY_CPU) {
12190 final StringBuilder sb = new StringBuilder();
12191 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid)
12193 TimeUtils.formatDuration(userTimeUs / 1000, sb);
12195 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
12196 Slog.d(TAG, sb.toString());
12199 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery);
12200 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery);
12201 if (updatedUids != null) {
12202 final int uid = timer.mUid.getUid();
12203 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs);
12206 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*");
12207 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery);
12209 mTempTotalCpuUserTimeUs -= userTimeUs;
12210 mTempTotalCpuSystemTimeUs -= systemTimeUs;
12216 * Take a snapshot of the cpu times spent by each uid in each freq and update the
12217 * corresponding counters.
12219 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed.
12222 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers,
12223 boolean onBattery, boolean onBatteryScreenOff) {
12224 final boolean perClusterTimesAvailable =
12225 mKernelUidCpuFreqTimeReader.perClusterTimesAvailable();
12226 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size();
12227 final int numClusters = mPowerProfile.getNumCpuClusters();
12228 mWakeLockAllocationsUs = null;
12229 final long startTimeMs = mClocks.uptimeMillis();
12230 mKernelUidCpuFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> {
12232 if (Process.isIsolated(uid)) {
12233 mKernelUidCpuFreqTimeReader.removeUid(uid);
12234 Slog.d(TAG, "Got freq readings for an isolated uid with no mapping: " + uid);
12237 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
12238 Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid);
12239 mKernelUidCpuFreqTimeReader.removeUid(uid);
12242 final Uid u = getUidStatsLocked(uid);
12243 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) {
12244 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase);
12246 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery);
12247 if (u.mScreenOffCpuFreqTimeMs == null ||
12248 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) {
12249 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
12250 mOnBatteryScreenOffTimeBase);
12252 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff);
12254 if (perClusterTimesAvailable) {
12255 if (u.mCpuClusterSpeedTimesUs == null ||
12256 u.mCpuClusterSpeedTimesUs.length != numClusters) {
12257 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
12259 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) {
12260 mWakeLockAllocationsUs = new long[numClusters][];
12264 for (int cluster = 0; cluster < numClusters; ++cluster) {
12265 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster);
12266 if (u.mCpuClusterSpeedTimesUs[cluster] == null ||
12267 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) {
12268 u.mCpuClusterSpeedTimesUs[cluster]
12269 = new LongSamplingCounter[speedsInCluster];
12271 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) {
12272 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster];
12274 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster];
12275 for (int speed = 0; speed < speedsInCluster; ++speed) {
12276 if (cpuTimesUs[speed] == null) {
12277 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
12279 final long appAllocationUs;
12280 if (mWakeLockAllocationsUs != null) {
12282 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100;
12283 mWakeLockAllocationsUs[cluster][speed] +=
12284 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs);
12286 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000;
12288 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery);
12295 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
12296 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
12297 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms");
12300 if (mWakeLockAllocationsUs != null) {
12301 for (int i = 0; i < numWakelocks; ++i) {
12302 final Uid u = partialTimers.get(i).mUid;
12303 if (u.mCpuClusterSpeedTimesUs == null ||
12304 u.mCpuClusterSpeedTimesUs.length != numClusters) {
12305 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
12308 for (int cluster = 0; cluster < numClusters; ++cluster) {
12309 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster);
12310 if (u.mCpuClusterSpeedTimesUs[cluster] == null ||
12311 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) {
12312 u.mCpuClusterSpeedTimesUs[cluster]
12313 = new LongSamplingCounter[speedsInCluster];
12315 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster];
12316 for (int speed = 0; speed < speedsInCluster; ++speed) {
12317 if (cpuTimeUs[speed] == null) {
12318 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
12320 final long allocationUs =
12321 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i);
12322 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery);
12323 mWakeLockAllocationsUs[cluster][speed] -= allocationUs;
12331 * Take a snapshot of the cpu active times spent by each uid and update the corresponding
12335 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) {
12336 final long startTimeMs = mClocks.uptimeMillis();
12337 mKernelUidCpuActiveTimeReader.readDelta((uid, cpuActiveTimesUs) -> {
12339 if (Process.isIsolated(uid)) {
12340 mKernelUidCpuActiveTimeReader.removeUid(uid);
12341 Slog.w(TAG, "Got active times for an isolated uid with no mapping: " + uid);
12344 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
12345 Slog.w(TAG, "Got active times for an invalid user's uid " + uid);
12346 mKernelUidCpuActiveTimeReader.removeUid(uid);
12349 final Uid u = getUidStatsLocked(uid);
12350 u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesUs, onBattery);
12353 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
12354 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
12355 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms");
12360 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding
12364 public void readKernelUidCpuClusterTimesLocked(boolean onBattery) {
12365 final long startTimeMs = mClocks.uptimeMillis();
12366 mKernelUidCpuClusterTimeReader.readDelta((uid, cpuClusterTimesUs) -> {
12368 if (Process.isIsolated(uid)) {
12369 mKernelUidCpuClusterTimeReader.removeUid(uid);
12370 Slog.w(TAG, "Got cluster times for an isolated uid with no mapping: " + uid);
12373 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
12374 Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid);
12375 mKernelUidCpuClusterTimeReader.removeUid(uid);
12378 final Uid u = getUidStatsLocked(uid);
12379 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesUs, onBattery);
12382 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
12383 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
12384 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms");
12388 boolean setChargingLocked(boolean charging) {
12389 if (mCharging != charging) {
12390 mCharging = charging;
12392 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
12394 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG;
12396 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING);
12403 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime,
12404 final boolean onBattery, final int oldStatus, final int level, final int chargeUAh) {
12405 boolean doWrite = false;
12406 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
12407 m.arg1 = onBattery ? 1 : 0;
12408 mHandler.sendMessage(m);
12410 final long uptime = mSecUptime * 1000;
12411 final long realtime = mSecRealtime * 1000;
12412 final int screenState = mScreenState;
12414 // We will reset our status if we are unplugging after the
12415 // battery was last full, or the level is at 100, or
12416 // we have gone through a significant charge (from a very low
12417 // level to a now very high level).
12418 boolean reset = false;
12419 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
12421 || (mDischargeCurrentLevel < 20 && level >= 80)
12422 || (getHighDischargeAmountSinceCharge() >= 200
12423 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) {
12424 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
12425 + " dischargeLevel=" + mDischargeCurrentLevel
12426 + " lowAmount=" + getLowDischargeAmountSinceCharge()
12427 + " highAmount=" + getHighDischargeAmountSinceCharge());
12428 // Before we write, collect a snapshot of the final aggregated
12429 // stats to be reported in the next checkin. Only do this if we have
12430 // a sufficient amount of data to make it interesting.
12431 if (getLowDischargeAmountSinceCharge() >= 20) {
12432 final long startTime = SystemClock.uptimeMillis();
12433 final Parcel parcel = Parcel.obtain();
12434 writeSummaryToParcel(parcel, true);
12435 final long initialTime = SystemClock.uptimeMillis() - startTime;
12436 BackgroundThread.getHandler().post(new Runnable() {
12437 @Override public void run() {
12438 synchronized (mCheckinFile) {
12439 final long startTime2 = SystemClock.uptimeMillis();
12440 FileOutputStream stream = null;
12442 stream = mCheckinFile.startWrite();
12443 stream.write(parcel.marshall());
12445 FileUtils.sync(stream);
12447 mCheckinFile.finishWrite(stream);
12448 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
12449 "batterystats-checkin",
12450 initialTime + SystemClock.uptimeMillis() - startTime2);
12451 } catch (IOException e) {
12452 Slog.w("BatteryStats",
12453 "Error writing checkin battery statistics", e);
12454 mCheckinFile.failWrite(stream);
12463 resetAllStatsLocked();
12464 if (chargeUAh > 0 && level > 0) {
12465 // Only use the reported coulomb charge value if it is supported and reported.
12466 mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0));
12468 mDischargeStartLevel = level;
12470 mDischargeStepTracker.init();
12473 setChargingLocked(false);
12475 mLastChargingStateLevel = level;
12476 mOnBattery = mOnBatteryInternal = true;
12477 mLastDischargeStepLevel = level;
12478 mMinDischargeStepLevel = level;
12479 mDischargeStepTracker.clearTime();
12480 mDailyDischargeStepTracker.clearTime();
12481 mInitStepMode = mCurStepMode;
12483 pullPendingStateUpdatesLocked();
12484 mHistoryCur.batteryLevel = (byte)level;
12485 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
12486 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
12487 + Integer.toHexString(mHistoryCur.states));
12489 mRecordingHistory = true;
12490 startRecordingHistory(mSecRealtime, mSecUptime, reset);
12492 addHistoryRecordLocked(mSecRealtime, mSecUptime);
12493 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
12494 if (isScreenOn(screenState)) {
12495 mDischargeScreenOnUnplugLevel = level;
12496 mDischargeScreenDozeUnplugLevel = 0;
12497 mDischargeScreenOffUnplugLevel = 0;
12498 } else if (isScreenDoze(screenState)) {
12499 mDischargeScreenOnUnplugLevel = 0;
12500 mDischargeScreenDozeUnplugLevel = level;
12501 mDischargeScreenOffUnplugLevel = 0;
12503 mDischargeScreenOnUnplugLevel = 0;
12504 mDischargeScreenDozeUnplugLevel = 0;
12505 mDischargeScreenOffUnplugLevel = level;
12507 mDischargeAmountScreenOn = 0;
12508 mDischargeAmountScreenDoze = 0;
12509 mDischargeAmountScreenOff = 0;
12510 updateTimeBasesLocked(true, screenState, uptime, realtime);
12512 mLastChargingStateLevel = level;
12513 mOnBattery = mOnBatteryInternal = false;
12514 pullPendingStateUpdatesLocked();
12515 mHistoryCur.batteryLevel = (byte)level;
12516 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
12517 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
12518 + Integer.toHexString(mHistoryCur.states));
12519 addHistoryRecordLocked(mSecRealtime, mSecUptime);
12520 mDischargeCurrentLevel = mDischargePlugLevel = level;
12521 if (level < mDischargeUnplugLevel) {
12522 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
12523 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
12525 updateDischargeScreenLevelsLocked(screenState, screenState);
12526 updateTimeBasesLocked(false, screenState, uptime, realtime);
12527 mChargeStepTracker.init();
12528 mLastChargeStepLevel = level;
12529 mMaxChargeStepLevel = level;
12530 mInitStepMode = mCurStepMode;
12533 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
12534 if (mFile != null) {
12535 writeAsyncLocked();
12540 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
12542 mRecordingHistory = true;
12543 mHistoryCur.currentTime = System.currentTimeMillis();
12544 addHistoryBufferLocked(elapsedRealtimeMs,
12545 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
12547 mHistoryCur.currentTime = 0;
12549 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
12553 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs,
12554 final long uptimeMs) {
12555 if (mRecordingHistory) {
12556 mHistoryCur.currentTime = currentTime;
12557 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur);
12558 mHistoryCur.currentTime = 0;
12562 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
12563 if (mRecordingHistory) {
12564 mHistoryCur.currentTime = System.currentTimeMillis();
12565 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur);
12566 mHistoryCur.currentTime = 0;
12570 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) {
12571 if (mExternalSync != null) {
12572 mExternalSync.scheduleSync(reason, updateFlags);
12576 // This should probably be exposed in the API, though it's not critical
12577 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0
12580 public void setBatteryStateLocked(final int status, final int health, final int plugType,
12581 final int level, /* not final */ int temp, final int volt, final int chargeUAh,
12582 final int chargeFullUAh) {
12583 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
12584 temp = Math.max(0, temp);
12586 reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null,
12587 status, plugType, level, temp);
12589 final boolean onBattery = isOnBattery(plugType, status);
12590 final long uptime = mClocks.uptimeMillis();
12591 final long elapsedRealtime = mClocks.elapsedRealtime();
12592 if (!mHaveBatteryLevel) {
12593 mHaveBatteryLevel = true;
12594 // We start out assuming that the device is plugged in (not
12595 // on battery). If our first report is now that we are indeed
12596 // plugged in, then twiddle our state to correctly reflect that
12597 // since we won't be going through the full setOnBattery().
12598 if (onBattery == mOnBattery) {
12600 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
12602 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
12605 // Always start out assuming charging, that will be updated later.
12606 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
12607 mHistoryCur.batteryStatus = (byte)status;
12608 mHistoryCur.batteryLevel = (byte)level;
12609 mHistoryCur.batteryChargeUAh = chargeUAh;
12610 mMaxChargeStepLevel = mMinDischargeStepLevel =
12611 mLastChargeStepLevel = mLastDischargeStepLevel = level;
12612 mLastChargingStateLevel = level;
12613 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
12614 recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
12616 int oldStatus = mHistoryCur.batteryStatus;
12618 mDischargeCurrentLevel = level;
12619 if (!mRecordingHistory) {
12620 mRecordingHistory = true;
12621 startRecordingHistory(elapsedRealtime, uptime, true);
12623 } else if (level < 96 &&
12624 status != BatteryManager.BATTERY_STATUS_UNKNOWN) {
12625 if (!mRecordingHistory) {
12626 mRecordingHistory = true;
12627 startRecordingHistory(elapsedRealtime, uptime, true);
12630 mCurrentBatteryLevel = level;
12631 if (mDischargePlugLevel < 0) {
12632 mDischargePlugLevel = level;
12635 if (onBattery != mOnBattery) {
12636 mHistoryCur.batteryLevel = (byte)level;
12637 mHistoryCur.batteryStatus = (byte)status;
12638 mHistoryCur.batteryHealth = (byte)health;
12639 mHistoryCur.batteryPlugType = (byte)plugType;
12640 mHistoryCur.batteryTemperature = (short)temp;
12641 mHistoryCur.batteryVoltage = (char)volt;
12642 if (chargeUAh < mHistoryCur.batteryChargeUAh) {
12643 // Only record discharges
12644 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh;
12645 mDischargeCounter.addCountLocked(chargeDiff);
12646 mDischargeScreenOffCounter.addCountLocked(chargeDiff);
12647 if (isScreenDoze(mScreenState)) {
12648 mDischargeScreenDozeCounter.addCountLocked(chargeDiff);
12650 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) {
12651 mDischargeLightDozeCounter.addCountLocked(chargeDiff);
12652 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) {
12653 mDischargeDeepDozeCounter.addCountLocked(chargeDiff);
12656 mHistoryCur.batteryChargeUAh = chargeUAh;
12657 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh);
12659 boolean changed = false;
12660 if (mHistoryCur.batteryLevel != level) {
12661 mHistoryCur.batteryLevel = (byte)level;
12664 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
12665 // which will pull external stats.
12666 scheduleSyncExternalStatsLocked("battery-level", ExternalStatsSync.UPDATE_ALL);
12668 if (mHistoryCur.batteryStatus != status) {
12669 mHistoryCur.batteryStatus = (byte)status;
12672 if (mHistoryCur.batteryHealth != health) {
12673 mHistoryCur.batteryHealth = (byte)health;
12676 if (mHistoryCur.batteryPlugType != plugType) {
12677 mHistoryCur.batteryPlugType = (byte)plugType;
12680 if (temp >= (mHistoryCur.batteryTemperature+10)
12681 || temp <= (mHistoryCur.batteryTemperature-10)) {
12682 mHistoryCur.batteryTemperature = (short)temp;
12685 if (volt > (mHistoryCur.batteryVoltage+20)
12686 || volt < (mHistoryCur.batteryVoltage-20)) {
12687 mHistoryCur.batteryVoltage = (char)volt;
12690 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10)
12691 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) {
12692 if (chargeUAh < mHistoryCur.batteryChargeUAh) {
12693 // Only record discharges
12694 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh;
12695 mDischargeCounter.addCountLocked(chargeDiff);
12696 mDischargeScreenOffCounter.addCountLocked(chargeDiff);
12697 if (isScreenDoze(mScreenState)) {
12698 mDischargeScreenDozeCounter.addCountLocked(chargeDiff);
12700 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) {
12701 mDischargeLightDozeCounter.addCountLocked(chargeDiff);
12702 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) {
12703 mDischargeDeepDozeCounter.addCountLocked(chargeDiff);
12706 mHistoryCur.batteryChargeUAh = chargeUAh;
12709 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
12710 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
12711 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
12713 changed |= setChargingLocked(false);
12714 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
12715 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
12716 modeBits, elapsedRealtime);
12717 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
12718 modeBits, elapsedRealtime);
12719 mLastDischargeStepLevel = level;
12720 mMinDischargeStepLevel = level;
12721 mInitStepMode = mCurStepMode;
12726 // If the battery level is at least 90%, always consider the device to be
12727 // charging even if it happens to go down a level.
12728 changed |= setChargingLocked(true);
12729 mLastChargeStepLevel = level;
12730 } if (!mCharging) {
12731 if (mLastChargeStepLevel < level) {
12732 // We have not reporting that we are charging, but the level has now
12733 // gone up, so consider the state to be charging.
12734 changed |= setChargingLocked(true);
12735 mLastChargeStepLevel = level;
12738 if (mLastChargeStepLevel > level) {
12739 // We had reported that the device was charging, but here we are with
12740 // power connected and the level going down. Looks like the current
12741 // power supplied isn't enough, so consider the device to now be
12743 changed |= setChargingLocked(false);
12744 mLastChargeStepLevel = level;
12747 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
12748 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
12749 modeBits, elapsedRealtime);
12750 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
12751 modeBits, elapsedRealtime);
12752 mLastChargeStepLevel = level;
12753 mMaxChargeStepLevel = level;
12754 mInitStepMode = mCurStepMode;
12759 addHistoryRecordLocked(elapsedRealtime, uptime);
12763 (status == BatteryManager.BATTERY_STATUS_FULL ||
12764 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) {
12765 // We don't record history while we are plugged in and fully charged
12766 // (or when battery is not present). The next time we are
12767 // unplugged, history will be cleared.
12768 mRecordingHistory = DEBUG;
12771 if (mMinLearnedBatteryCapacity == -1) {
12772 mMinLearnedBatteryCapacity = chargeFullUAh;
12774 Math.min(mMinLearnedBatteryCapacity, chargeFullUAh);
12776 mMaxLearnedBatteryCapacity = Math.max(mMaxLearnedBatteryCapacity, chargeFullUAh);
12779 public static boolean isOnBattery(int plugType, int status) {
12780 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN;
12783 // Inform StatsLog of setBatteryState changes.
12784 // If this is the first reporting, pass in recentPast == null.
12785 private void reportChangesToStatsLog(HistoryItem recentPast,
12786 final int status, final int plugType, final int level, final int temp) {
12788 if (recentPast == null || recentPast.batteryStatus != status) {
12789 StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, status);
12791 if (recentPast == null || recentPast.batteryPlugType != plugType) {
12792 StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED, plugType);
12794 if (recentPast == null || recentPast.batteryLevel != level) {
12795 StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, level);
12797 // Let's just always print the temperature, regardless of whether it changed.
12798 StatsLog.write(StatsLog.DEVICE_TEMPERATURE_REPORTED, temp);
12801 public long getAwakeTimeBattery() {
12802 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
12805 public long getAwakeTimePlugged() {
12806 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery();
12810 public long computeUptime(long curTime, int which) {
12812 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
12813 case STATS_CURRENT: return (curTime-mUptimeStart);
12814 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
12820 public long computeRealtime(long curTime, int which) {
12822 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
12823 case STATS_CURRENT: return (curTime-mRealtimeStart);
12824 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
12830 public long computeBatteryUptime(long curTime, int which) {
12831 return mOnBatteryTimeBase.computeUptime(curTime, which);
12835 public long computeBatteryRealtime(long curTime, int which) {
12836 return mOnBatteryTimeBase.computeRealtime(curTime, which);
12840 public long computeBatteryScreenOffUptime(long curTime, int which) {
12841 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
12845 public long computeBatteryScreenOffRealtime(long curTime, int which) {
12846 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
12849 private long computeTimePerLevel(long[] steps, int numSteps) {
12850 // For now we'll do a simple average across all steps.
12851 if (numSteps <= 0) {
12855 for (int i=0; i<numSteps; i++) {
12856 total += steps[i] & STEP_LEVEL_TIME_MASK;
12858 return total / numSteps;
12860 long[] buckets = new long[numSteps];
12861 int numBuckets = 0;
12862 int numToAverage = 4;
12864 while (i < numSteps) {
12865 long totalTime = 0;
12867 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
12868 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
12871 buckets[numBuckets] = totalTime / num;
12876 if (numBuckets < 1) {
12879 long averageTime = buckets[numBuckets-1];
12880 for (i=numBuckets-2; i>=0; i--) {
12881 averageTime = (averageTime + buckets[i]) / 2;
12883 return averageTime;
12888 public long computeBatteryTimeRemaining(long curTime) {
12892 /* Simple implementation just looks at the average discharge per level across the
12893 entire sample period.
12894 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2;
12895 if (discharge < 2) {
12898 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED);
12899 if (duration < 1000*1000) {
12902 long usPerLevel = duration/discharge;
12903 return usPerLevel * mCurrentBatteryLevel;
12905 if (mDischargeStepTracker.mNumStepDurations < 1) {
12908 long msPerLevel = mDischargeStepTracker.computeTimePerLevel();
12909 if (msPerLevel <= 0) {
12912 return (msPerLevel * mCurrentBatteryLevel) * 1000;
12916 public LevelStepTracker getDischargeLevelStepTracker() {
12917 return mDischargeStepTracker;
12921 public LevelStepTracker getDailyDischargeLevelStepTracker() {
12922 return mDailyDischargeStepTracker;
12926 public long computeChargeTimeRemaining(long curTime) {
12928 // Not yet working.
12932 int curLevel = mCurrentBatteryLevel;
12933 int plugLevel = mDischargePlugLevel;
12934 if (plugLevel < 0 || curLevel < (plugLevel+1)) {
12937 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED);
12938 if (duration < 1000*1000) {
12941 long usPerLevel = duration/(curLevel-plugLevel);
12942 return usPerLevel * (100-curLevel);
12944 if (mChargeStepTracker.mNumStepDurations < 1) {
12947 long msPerLevel = mChargeStepTracker.computeTimePerLevel();
12948 if (msPerLevel <= 0) {
12951 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
12955 public CellularBatteryStats getCellularBatteryStats() {
12956 CellularBatteryStats s = new CellularBatteryStats();
12957 final int which = STATS_SINCE_CHARGED;
12958 final long rawRealTime = SystemClock.elapsedRealtime() * 1000;
12959 final ControllerActivityCounter counter = getModemControllerActivity();
12960 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
12961 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
12962 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which);
12963 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES];
12964 for (int i = 0; i < timeInRatMs.length; i++) {
12965 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTime, which) / 1000;
12967 long[] timeInRxSignalStrengthLevelMs = new long[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
12968 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) {
12969 timeInRxSignalStrengthLevelMs[i]
12970 = getPhoneSignalStrengthTime(i, rawRealTime, which) / 1000;
12972 long[] txTimeMs = new long[Math.min(ModemActivityInfo.TX_POWER_LEVELS,
12973 counter.getTxTimeCounters().length)];
12974 long totalTxTimeMs = 0;
12975 for (int i = 0; i < txTimeMs.length; i++) {
12976 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which);
12977 totalTxTimeMs += txTimeMs[i];
12979 final long totalControllerActivityTimeMs
12980 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
12981 final long sleepTimeMs
12982 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + totalTxTimeMs);
12983 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000);
12984 s.setKernelActiveTimeMs(getMobileRadioActiveTime(rawRealTime, which) / 1000);
12985 s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
12986 s.setNumBytesTx(getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which));
12987 s.setNumPacketsRx(getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which));
12988 s.setNumBytesRx(getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which));
12989 s.setSleepTimeMs(sleepTimeMs);
12990 s.setIdleTimeMs(idleTimeMs);
12991 s.setRxTimeMs(rxTimeMs);
12992 s.setEnergyConsumedMaMs(energyConsumedMaMs);
12993 s.setTimeInRatMs(timeInRatMs);
12994 s.setTimeInRxSignalStrengthLevelMs(timeInRxSignalStrengthLevelMs);
12995 s.setTxTimeMs(txTimeMs);
13000 public WifiBatteryStats getWifiBatteryStats() {
13001 WifiBatteryStats s = new WifiBatteryStats();
13002 final int which = STATS_SINCE_CHARGED;
13003 final long rawRealTime = SystemClock.elapsedRealtime() * 1000;
13004 final ControllerActivityCounter counter = getWifiControllerActivity();
13005 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
13006 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which);
13007 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
13008 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which);
13009 final long totalControllerActivityTimeMs
13010 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
13011 final long sleepTimeMs
13012 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs);
13013 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which);
13014 long numAppScanRequest = 0;
13015 for (int i = 0; i < mUidStats.size(); i++) {
13016 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which);
13018 long[] timeInStateMs = new long[NUM_WIFI_STATES];
13019 for (int i=0; i<NUM_WIFI_STATES; i++) {
13020 timeInStateMs[i] = getWifiStateTime(i, rawRealTime, which) / 1000;
13022 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES];
13023 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
13024 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTime, which) / 1000;
13026 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS];
13027 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
13028 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTime, which) / 1000;
13030 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000);
13031 s.setKernelActiveTimeMs(getWifiActiveTime(rawRealTime, which) / 1000);
13032 s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
13033 s.setNumBytesTx(getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
13034 s.setNumPacketsRx(getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
13035 s.setNumBytesRx(getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
13036 s.setSleepTimeMs(sleepTimeMs);
13037 s.setIdleTimeMs(idleTimeMs);
13038 s.setRxTimeMs(rxTimeMs);
13039 s.setTxTimeMs(txTimeMs);
13040 s.setScanTimeMs(scanTimeMs);
13041 s.setEnergyConsumedMaMs(energyConsumedMaMs);
13042 s.setNumAppScanRequest(numAppScanRequest);
13043 s.setTimeInStateMs(timeInStateMs);
13044 s.setTimeInSupplicantStateMs(timeInSupplStateMs);
13045 s.setTimeInRxSignalStrengthLevelMs(timeSignalStrengthTimeMs);
13050 public GpsBatteryStats getGpsBatteryStats() {
13051 GpsBatteryStats s = new GpsBatteryStats();
13052 final int which = STATS_SINCE_CHARGED;
13053 final long rawRealTime = SystemClock.elapsedRealtime() * 1000;
13054 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000);
13055 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs());
13056 long[] time = new long[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS];
13057 for (int i=0; i<time.length; i++) {
13058 time[i] = getGpsSignalQualityTime(i, rawRealTime, which) / 1000;
13060 s.setTimeInGpsSignalQualityLevel(time);
13065 public LevelStepTracker getChargeLevelStepTracker() {
13066 return mChargeStepTracker;
13070 public LevelStepTracker getDailyChargeLevelStepTracker() {
13071 return mDailyChargeStepTracker;
13075 public ArrayList<PackageChange> getDailyPackageChanges() {
13076 return mDailyPackageChanges;
13079 protected long getBatteryUptimeLocked() {
13080 return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000);
13084 public long getBatteryUptime(long curTime) {
13085 return mOnBatteryTimeBase.getUptime(curTime);
13089 public long getBatteryRealtime(long curTime) {
13090 return mOnBatteryTimeBase.getRealtime(curTime);
13094 public int getDischargeStartLevel() {
13095 synchronized(this) {
13096 return getDischargeStartLevelLocked();
13100 public int getDischargeStartLevelLocked() {
13101 return mDischargeUnplugLevel;
13105 public int getDischargeCurrentLevel() {
13106 synchronized(this) {
13107 return getDischargeCurrentLevelLocked();
13111 public int getDischargeCurrentLevelLocked() {
13112 return mDischargeCurrentLevel;
13116 public int getLowDischargeAmountSinceCharge() {
13117 synchronized(this) {
13118 int val = mLowDischargeAmountSinceCharge;
13119 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
13120 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
13127 public int getHighDischargeAmountSinceCharge() {
13128 synchronized(this) {
13129 int val = mHighDischargeAmountSinceCharge;
13130 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
13131 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
13138 public int getDischargeAmount(int which) {
13139 int dischargeAmount = which == STATS_SINCE_CHARGED
13140 ? getHighDischargeAmountSinceCharge()
13141 : (getDischargeStartLevel() - getDischargeCurrentLevel());
13142 if (dischargeAmount < 0) {
13143 dischargeAmount = 0;
13145 return dischargeAmount;
13149 public int getDischargeAmountScreenOn() {
13150 synchronized(this) {
13151 int val = mDischargeAmountScreenOn;
13152 if (mOnBattery && isScreenOn(mScreenState)
13153 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
13154 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
13161 public int getDischargeAmountScreenOnSinceCharge() {
13162 synchronized(this) {
13163 int val = mDischargeAmountScreenOnSinceCharge;
13164 if (mOnBattery && isScreenOn(mScreenState)
13165 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
13166 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
13173 public int getDischargeAmountScreenOff() {
13174 synchronized(this) {
13175 int val = mDischargeAmountScreenOff;
13176 if (mOnBattery && isScreenOff(mScreenState)
13177 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
13178 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
13180 // For backward compatibility, doze discharge is counted into screen off.
13181 return val + getDischargeAmountScreenDoze();
13186 public int getDischargeAmountScreenOffSinceCharge() {
13187 synchronized(this) {
13188 int val = mDischargeAmountScreenOffSinceCharge;
13189 if (mOnBattery && isScreenOff(mScreenState)
13190 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
13191 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
13193 // For backward compatibility, doze discharge is counted into screen off.
13194 return val + getDischargeAmountScreenDozeSinceCharge();
13199 public int getDischargeAmountScreenDoze() {
13200 synchronized(this) {
13201 int val = mDischargeAmountScreenDoze;
13202 if (mOnBattery && isScreenDoze(mScreenState)
13203 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) {
13204 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel;
13211 public int getDischargeAmountScreenDozeSinceCharge() {
13212 synchronized(this) {
13213 int val = mDischargeAmountScreenDozeSinceCharge;
13214 if (mOnBattery && isScreenDoze(mScreenState)
13215 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) {
13216 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel;
13223 * Retrieve the statistics object for a particular uid, creating if needed.
13225 public Uid getUidStatsLocked(int uid) {
13226 Uid u = mUidStats.get(uid);
13228 u = new Uid(this, uid);
13229 mUidStats.put(uid, u);
13235 * Retrieve the statistics object for a particular uid. Returns null if the object is not
13238 public Uid getAvailableUidStatsLocked(int uid) {
13239 Uid u = mUidStats.get(uid);
13243 public void onCleanupUserLocked(int userId) {
13244 final int firstUidForUser = UserHandle.getUid(userId, 0);
13245 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1);
13246 mKernelUidCpuFreqTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
13247 mKernelUidCpuTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
13248 if (mKernelSingleUidTimeReader != null) {
13249 mKernelSingleUidTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
13253 public void onUserRemovedLocked(int userId) {
13254 final int firstUidForUser = UserHandle.getUid(userId, 0);
13255 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1);
13256 mUidStats.put(firstUidForUser, null);
13257 mUidStats.put(lastUidForUser, null);
13258 final int firstIndex = mUidStats.indexOfKey(firstUidForUser);
13259 final int lastIndex = mUidStats.indexOfKey(lastUidForUser);
13260 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1);
13264 * Remove the statistics object for a particular uid.
13266 public void removeUidStatsLocked(int uid) {
13267 mKernelUidCpuTimeReader.removeUid(uid);
13268 mKernelUidCpuFreqTimeReader.removeUid(uid);
13269 if (mKernelSingleUidTimeReader != null) {
13270 mKernelSingleUidTimeReader.removeUid(uid);
13272 mUidStats.remove(uid);
13276 * Retrieve the statistics object for a particular process, creating
13279 public Uid.Proc getProcessStatsLocked(int uid, String name) {
13281 Uid u = getUidStatsLocked(uid);
13282 return u.getProcessStatsLocked(name);
13286 * Retrieve the statistics object for a particular process, creating
13289 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
13291 Uid u = getUidStatsLocked(uid);
13292 return u.getPackageStatsLocked(pkg);
13296 * Retrieve the statistics object for a particular service, creating
13299 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
13301 Uid u = getUidStatsLocked(uid);
13302 return u.getServiceStatsLocked(pkg, name);
13305 public void shutdownLocked() {
13306 recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
13308 mShuttingDown = true;
13311 public boolean trackPerProcStateCpuTimes() {
13312 return mConstants.TRACK_CPU_TIMES_BY_PROC_STATE && mPerProcStateCpuTimesAvailable;
13315 public void systemServicesReady(Context context) {
13316 mConstants.startObserving(context.getContentResolver());
13320 public final class Constants extends ContentObserver {
13321 public static final String KEY_TRACK_CPU_TIMES_BY_PROC_STATE
13322 = "track_cpu_times_by_proc_state";
13323 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME
13324 = "track_cpu_active_cluster_time";
13325 public static final String KEY_READ_BINARY_CPU_TIME
13326 = "read_binary_cpu_time";
13327 public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS
13328 = "proc_state_cpu_times_read_delay_ms";
13330 private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true;
13331 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true;
13332 private static final boolean DEFAULT_READ_BINARY_CPU_TIME = false;
13333 private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_000;
13335 public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE;
13336 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME;
13337 // Not used right now.
13338 public boolean READ_BINARY_CPU_TIME = DEFAULT_READ_BINARY_CPU_TIME;
13339 public long PROC_STATE_CPU_TIMES_READ_DELAY_MS = DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS;
13341 private ContentResolver mResolver;
13342 private final KeyValueListParser mParser = new KeyValueListParser(',');
13344 public Constants(Handler handler) {
13348 public void startObserving(ContentResolver resolver) {
13349 mResolver = resolver;
13350 mResolver.registerContentObserver(
13351 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS),
13352 false /* notifyForDescendants */, this);
13357 public void onChange(boolean selfChange, Uri uri) {
13361 private void updateConstants() {
13362 synchronized (BatteryStatsImpl.this) {
13364 mParser.setString(Settings.Global.getString(mResolver,
13365 Settings.Global.BATTERY_STATS_CONSTANTS));
13366 } catch (IllegalArgumentException e) {
13367 // Failed to parse the settings string, log this and move on
13369 Slog.e(TAG, "Bad batterystats settings", e);
13372 updateTrackCpuTimesByProcStateLocked(TRACK_CPU_TIMES_BY_PROC_STATE,
13373 mParser.getBoolean(KEY_TRACK_CPU_TIMES_BY_PROC_STATE,
13374 DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE));
13375 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean(
13376 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME);
13377 READ_BINARY_CPU_TIME = mParser.getBoolean(
13378 KEY_READ_BINARY_CPU_TIME, DEFAULT_READ_BINARY_CPU_TIME);
13379 updateProcStateCpuTimesReadDelayMs(PROC_STATE_CPU_TIMES_READ_DELAY_MS,
13380 mParser.getLong(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS,
13381 DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS));
13385 private void updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled) {
13386 TRACK_CPU_TIMES_BY_PROC_STATE = isEnabled;
13387 if (isEnabled && !wasEnabled) {
13388 mKernelSingleUidTimeReader.markDataAsStale(true);
13389 mExternalSync.scheduleCpuSyncDueToSettingChange();
13391 mNumCpuTimeReads = 0;
13392 mNumBatchedCpuTimeReads = 0;
13393 mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis();
13397 private void updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis) {
13398 PROC_STATE_CPU_TIMES_READ_DELAY_MS = newDelayMillis;
13399 if (oldDelayMillis != newDelayMillis) {
13400 mNumCpuTimeReads = 0;
13401 mNumBatchedCpuTimeReads = 0;
13402 mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis();
13406 public void dumpLocked(PrintWriter pw) {
13407 pw.print(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); pw.print("=");
13408 pw.println(TRACK_CPU_TIMES_BY_PROC_STATE);
13409 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("=");
13410 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME);
13411 pw.print(KEY_READ_BINARY_CPU_TIME); pw.print("=");
13412 pw.println(READ_BINARY_CPU_TIME);
13413 pw.print(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS); pw.print("=");
13414 pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS);
13419 public void dumpConstantsLocked(PrintWriter pw) {
13420 mConstants.dumpLocked(pw);
13423 Parcel mPendingWrite = null;
13424 final ReentrantLock mWriteLock = new ReentrantLock();
13426 public void writeAsyncLocked() {
13427 writeLocked(false);
13430 public void writeSyncLocked() {
13434 void writeLocked(boolean sync) {
13435 if (mFile == null) {
13436 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
13440 if (mShuttingDown) {
13444 Parcel out = Parcel.obtain();
13445 writeSummaryToParcel(out, true);
13446 mLastWriteTime = mClocks.elapsedRealtime();
13448 if (mPendingWrite != null) {
13449 mPendingWrite.recycle();
13451 mPendingWrite = out;
13454 commitPendingDataToDisk();
13456 BackgroundThread.getHandler().post(new Runnable() {
13457 @Override public void run() {
13458 commitPendingDataToDisk();
13464 public void commitPendingDataToDisk() {
13466 synchronized (this) {
13467 next = mPendingWrite;
13468 mPendingWrite = null;
13469 if (next == null) {
13476 final long startTime = SystemClock.uptimeMillis();
13477 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
13478 stream.write(next.marshall());
13480 FileUtils.sync(stream);
13483 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
13484 "batterystats", SystemClock.uptimeMillis() - startTime);
13485 } catch (IOException e) {
13486 Slog.w("BatteryStats", "Error writing battery statistics", e);
13490 mWriteLock.unlock();
13494 public void readLocked() {
13495 if (mDailyFile != null) {
13496 readDailyStatsLocked();
13499 if (mFile == null) {
13500 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
13507 File file = mFile.chooseForRead();
13508 if (!file.exists()) {
13511 FileInputStream stream = new FileInputStream(file);
13513 byte[] raw = BatteryStatsHelper.readFully(stream);
13514 Parcel in = Parcel.obtain();
13515 in.unmarshall(raw, 0, raw.length);
13516 in.setDataPosition(0);
13519 readSummaryFromParcel(in);
13520 } catch(Exception e) {
13521 Slog.e("BatteryStats", "Error reading battery statistics", e);
13522 resetAllStatsLocked();
13525 mEndPlatformVersion = Build.ID;
13527 if (mHistoryBuffer.dataPosition() > 0) {
13528 mRecordingHistory = true;
13529 final long elapsedRealtime = mClocks.elapsedRealtime();
13530 final long uptime = mClocks.uptimeMillis();
13531 if (USE_OLD_HISTORY) {
13532 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
13534 addHistoryBufferLocked(elapsedRealtime, HistoryItem.CMD_START, mHistoryCur);
13535 startRecordingHistory(elapsedRealtime, uptime, false);
13538 recordDailyStatsIfNeededLocked(false);
13541 public int describeContents() {
13545 void readHistory(Parcel in, boolean andOldHistory) throws ParcelFormatException {
13546 final long historyBaseTime = in.readLong();
13548 mHistoryBuffer.setDataSize(0);
13549 mHistoryBuffer.setDataPosition(0);
13550 mHistoryTagPool.clear();
13551 mNextHistoryTagIdx = 0;
13552 mNumHistoryTagChars = 0;
13554 int numTags = in.readInt();
13555 for (int i=0; i<numTags; i++) {
13556 int idx = in.readInt();
13557 String str = in.readString();
13559 throw new ParcelFormatException("null history tag string");
13561 int uid = in.readInt();
13562 HistoryTag tag = new HistoryTag();
13566 mHistoryTagPool.put(tag, idx);
13567 if (idx >= mNextHistoryTagIdx) {
13568 mNextHistoryTagIdx = idx+1;
13570 mNumHistoryTagChars += tag.string.length() + 1;
13573 int bufSize = in.readInt();
13574 int curPos = in.dataPosition();
13575 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
13576 throw new ParcelFormatException("File corrupt: history data buffer too large " +
13578 } else if ((bufSize&~3) != bufSize) {
13579 throw new ParcelFormatException("File corrupt: history data buffer not aligned " +
13582 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
13583 + " bytes at " + curPos);
13584 mHistoryBuffer.appendFrom(in, curPos, bufSize);
13585 in.setDataPosition(curPos + bufSize);
13588 if (andOldHistory) {
13589 readOldHistory(in);
13592 if (DEBUG_HISTORY) {
13593 StringBuilder sb = new StringBuilder(128);
13594 sb.append("****************** OLD mHistoryBaseTime: ");
13595 TimeUtils.formatDuration(mHistoryBaseTime, sb);
13596 Slog.i(TAG, sb.toString());
13598 mHistoryBaseTime = historyBaseTime;
13599 if (DEBUG_HISTORY) {
13600 StringBuilder sb = new StringBuilder(128);
13601 sb.append("****************** NEW mHistoryBaseTime: ");
13602 TimeUtils.formatDuration(mHistoryBaseTime, sb);
13603 Slog.i(TAG, sb.toString());
13606 // We are just arbitrarily going to insert 1 minute from the sample of
13607 // the last run until samples in this run.
13608 if (mHistoryBaseTime > 0) {
13609 long oldnow = mClocks.elapsedRealtime();
13610 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1;
13611 if (DEBUG_HISTORY) {
13612 StringBuilder sb = new StringBuilder(128);
13613 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
13614 TimeUtils.formatDuration(mHistoryBaseTime, sb);
13615 Slog.i(TAG, sb.toString());
13620 void readOldHistory(Parcel in) {
13621 if (!USE_OLD_HISTORY) {
13624 mHistory = mHistoryEnd = mHistoryCache = null;
13626 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
13627 HistoryItem rec = new HistoryItem(time, in);
13628 addHistoryRecordLocked(rec);
13632 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) {
13633 if (DEBUG_HISTORY) {
13634 StringBuilder sb = new StringBuilder(128);
13635 sb.append("****************** WRITING mHistoryBaseTime: ");
13636 TimeUtils.formatDuration(mHistoryBaseTime, sb);
13637 sb.append(" mLastHistoryElapsedRealtime: ");
13638 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
13639 Slog.i(TAG, sb.toString());
13641 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
13647 out.writeInt(mHistoryTagPool.size());
13648 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
13649 HistoryTag tag = ent.getKey();
13650 out.writeInt(ent.getValue());
13651 out.writeString(tag.string);
13652 out.writeInt(tag.uid);
13654 out.writeInt(mHistoryBuffer.dataSize());
13655 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
13656 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
13657 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
13659 if (andOldHistory) {
13660 writeOldHistory(out);
13664 void writeOldHistory(Parcel out) {
13665 if (!USE_OLD_HISTORY) {
13668 HistoryItem rec = mHistory;
13669 while (rec != null) {
13670 if (rec.time >= 0) rec.writeToParcel(out, 0);
13676 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException {
13677 final int version = in.readInt();
13678 if (version != VERSION) {
13679 Slog.w("BatteryStats", "readFromParcel: version got " + version
13680 + ", expected " + VERSION + "; erasing old stats");
13684 readHistory(in, true);
13686 mStartCount = in.readInt();
13687 mUptime = in.readLong();
13688 mRealtime = in.readLong();
13689 mStartClockTime = in.readLong();
13690 mStartPlatformVersion = in.readString();
13691 mEndPlatformVersion = in.readString();
13692 mOnBatteryTimeBase.readSummaryFromParcel(in);
13693 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
13694 mDischargeUnplugLevel = in.readInt();
13695 mDischargePlugLevel = in.readInt();
13696 mDischargeCurrentLevel = in.readInt();
13697 mCurrentBatteryLevel = in.readInt();
13698 mEstimatedBatteryCapacity = in.readInt();
13699 mMinLearnedBatteryCapacity = in.readInt();
13700 mMaxLearnedBatteryCapacity = in.readInt();
13701 mLowDischargeAmountSinceCharge = in.readInt();
13702 mHighDischargeAmountSinceCharge = in.readInt();
13703 mDischargeAmountScreenOnSinceCharge = in.readInt();
13704 mDischargeAmountScreenOffSinceCharge = in.readInt();
13705 mDischargeAmountScreenDozeSinceCharge = in.readInt();
13706 mDischargeStepTracker.readFromParcel(in);
13707 mChargeStepTracker.readFromParcel(in);
13708 mDailyDischargeStepTracker.readFromParcel(in);
13709 mDailyChargeStepTracker.readFromParcel(in);
13710 mDischargeCounter.readSummaryFromParcelLocked(in);
13711 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in);
13712 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in);
13713 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in);
13714 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in);
13715 int NPKG = in.readInt();
13717 mDailyPackageChanges = new ArrayList<>(NPKG);
13720 PackageChange pc = new PackageChange();
13721 pc.mPackageName = in.readString();
13722 pc.mUpdate = in.readInt() != 0;
13723 pc.mVersionCode = in.readLong();
13724 mDailyPackageChanges.add(pc);
13727 mDailyPackageChanges = null;
13729 mDailyStartTime = in.readLong();
13730 mNextMinDailyDeadline = in.readLong();
13731 mNextMaxDailyDeadline = in.readLong();
13735 mScreenState = Display.STATE_UNKNOWN;
13736 mScreenOnTimer.readSummaryFromParcelLocked(in);
13737 mScreenDozeTimer.readSummaryFromParcelLocked(in);
13738 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
13739 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
13741 mInteractive = false;
13742 mInteractiveTimer.readSummaryFromParcelLocked(in);
13744 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in);
13745 mLongestLightIdleTime = in.readLong();
13746 mLongestFullIdleTime = in.readLong();
13747 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in);
13748 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in);
13749 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in);
13750 mDeviceIdlingTimer.readSummaryFromParcelLocked(in);
13751 mPhoneOnTimer.readSummaryFromParcelLocked(in);
13752 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
13753 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
13755 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
13756 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
13757 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
13759 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
13760 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
13761 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
13763 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
13764 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
13765 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
13766 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
13767 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
13768 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
13769 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in);
13770 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
13772 mWifiOnTimer.readSummaryFromParcelLocked(in);
13773 mGlobalWifiRunning = false;
13774 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
13775 for (int i=0; i<NUM_WIFI_STATES; i++) {
13776 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
13778 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
13779 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in);
13781 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
13782 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
13784 mWifiActiveTimer.readSummaryFromParcelLocked(in);
13785 mWifiActivity.readSummaryFromParcel(in);
13786 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
13787 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in);
13789 mBluetoothActivity.readSummaryFromParcel(in);
13790 mModemActivity.readSummaryFromParcel(in);
13791 mHasWifiReporting = in.readInt() != 0;
13792 mHasBluetoothReporting = in.readInt() != 0;
13793 mHasModemReporting = in.readInt() != 0;
13795 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
13796 mFlashlightOnNesting = 0;
13797 mFlashlightOnTimer.readSummaryFromParcelLocked(in);
13798 mCameraOnNesting = 0;
13799 mCameraOnTimer.readSummaryFromParcelLocked(in);
13800 mBluetoothScanNesting = 0;
13801 mBluetoothScanTimer.readSummaryFromParcelLocked(in);
13802 mIsCellularTxPowerHigh = false;
13804 int NRPMS = in.readInt();
13805 if (NRPMS > 10000) {
13806 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS);
13808 for (int irpm = 0; irpm < NRPMS; irpm++) {
13809 if (in.readInt() != 0) {
13810 String rpmName = in.readString();
13811 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in);
13814 int NSORPMS = in.readInt();
13815 if (NSORPMS > 10000) {
13816 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS);
13818 for (int irpm = 0; irpm < NSORPMS; irpm++) {
13819 if (in.readInt() != 0) {
13820 String rpmName = in.readString();
13821 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in);
13825 int NKW = in.readInt();
13827 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW);
13829 for (int ikw = 0; ikw < NKW; ikw++) {
13830 if (in.readInt() != 0) {
13831 String kwltName = in.readString();
13832 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
13836 int NWR = in.readInt();
13838 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR);
13840 for (int iwr = 0; iwr < NWR; iwr++) {
13841 if (in.readInt() != 0) {
13842 String reasonName = in.readString();
13843 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in);
13847 int NMS = in.readInt();
13848 for (int ims = 0; ims < NMS; ims++) {
13849 if (in.readInt() != 0) {
13850 long kmstName = in.readLong();
13851 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in);
13855 final int NU = in.readInt();
13857 throw new ParcelFormatException("File corrupt: too many uids " + NU);
13859 for (int iu = 0; iu < NU; iu++) {
13860 int uid = in.readInt();
13861 Uid u = new Uid(this, uid);
13862 mUidStats.put(uid, u);
13864 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in);
13865 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in);
13867 u.mWifiRunning = false;
13868 if (in.readInt() != 0) {
13869 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
13871 u.mFullWifiLockOut = false;
13872 if (in.readInt() != 0) {
13873 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
13875 u.mWifiScanStarted = false;
13876 if (in.readInt() != 0) {
13877 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
13879 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
13880 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
13881 if (in.readInt() != 0) {
13882 u.makeWifiBatchedScanBin(i, null);
13883 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
13886 u.mWifiMulticastEnabled = false;
13887 if (in.readInt() != 0) {
13888 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
13890 if (in.readInt() != 0) {
13891 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
13893 if (in.readInt() != 0) {
13894 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
13896 if (in.readInt() != 0) {
13897 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
13899 if (in.readInt() != 0) {
13900 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
13902 if (in.readInt() != 0) {
13903 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
13905 if (in.readInt() != 0) {
13906 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in);
13908 if (in.readInt() != 0) {
13909 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in);
13911 if (in.readInt() != 0) {
13912 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in);
13914 if (in.readInt() != 0) {
13915 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in);
13917 if (in.readInt() != 0) {
13918 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in);
13920 if (in.readInt() != 0) {
13921 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in);
13923 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
13924 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
13925 if (in.readInt() != 0) {
13926 u.makeProcessState(i, null);
13927 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in);
13930 if (in.readInt() != 0) {
13931 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
13934 if (in.readInt() != 0) {
13935 if (u.mUserActivityCounters == null) {
13936 u.initUserActivityLocked();
13938 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
13939 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
13943 if (in.readInt() != 0) {
13944 if (u.mNetworkByteActivityCounters == null) {
13945 u.initNetworkActivityLocked();
13947 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
13948 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
13949 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
13951 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
13952 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
13955 u.mUserCpuTime.readSummaryFromParcelLocked(in);
13956 u.mSystemCpuTime.readSummaryFromParcelLocked(in);
13958 if (in.readInt() != 0) {
13959 final int numClusters = in.readInt();
13960 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) {
13961 throw new ParcelFormatException("Incompatible cpu cluster arrangement");
13964 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
13965 for (int cluster = 0; cluster < numClusters; cluster++) {
13966 if (in.readInt() != 0) {
13967 final int NSB = in.readInt();
13968 if (mPowerProfile != null &&
13969 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) {
13970 throw new ParcelFormatException("File corrupt: too many speed bins " +
13974 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB];
13975 for (int speed = 0; speed < NSB; speed++) {
13976 if (in.readInt() != 0) {
13977 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter(
13978 mOnBatteryTimeBase);
13979 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in);
13983 u.mCpuClusterSpeedTimesUs[cluster] = null;
13987 u.mCpuClusterSpeedTimesUs = null;
13990 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
13991 in, mOnBatteryTimeBase);
13992 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
13993 in, mOnBatteryScreenOffTimeBase);
13995 u.mCpuActiveTimeMs.readSummaryFromParcelLocked(in);
13996 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in);
13998 int length = in.readInt();
13999 if (length == Uid.NUM_PROCESS_STATE) {
14000 u.mProcStateTimeMs = new LongSamplingCounterArray[length];
14001 for (int procState = 0; procState < length; ++procState) {
14002 u.mProcStateTimeMs[procState]
14003 = LongSamplingCounterArray.readSummaryFromParcelLocked(
14004 in, mOnBatteryTimeBase);
14007 u.mProcStateTimeMs = null;
14009 length = in.readInt();
14010 if (length == Uid.NUM_PROCESS_STATE) {
14011 u.mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length];
14012 for (int procState = 0; procState < length; ++procState) {
14013 u.mProcStateScreenOffTimeMs[procState]
14014 = LongSamplingCounterArray.readSummaryFromParcelLocked(
14015 in, mOnBatteryScreenOffTimeBase);
14018 u.mProcStateScreenOffTimeMs = null;
14021 if (in.readInt() != 0) {
14022 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase);
14023 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in);
14025 u.mMobileRadioApWakeupCount = null;
14028 if (in.readInt() != 0) {
14029 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase);
14030 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in);
14032 u.mWifiRadioApWakeupCount = null;
14035 int NW = in.readInt();
14036 if (NW > (MAX_WAKELOCKS_PER_UID+1)) {
14037 throw new ParcelFormatException("File corrupt: too many wake locks " + NW);
14039 for (int iw = 0; iw < NW; iw++) {
14040 String wlName = in.readString();
14041 u.readWakeSummaryFromParcelLocked(wlName, in);
14044 int NS = in.readInt();
14045 if (NS > (MAX_WAKELOCKS_PER_UID+1)) {
14046 throw new ParcelFormatException("File corrupt: too many syncs " + NS);
14048 for (int is = 0; is < NS; is++) {
14049 String name = in.readString();
14050 u.readSyncSummaryFromParcelLocked(name, in);
14053 int NJ = in.readInt();
14054 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) {
14055 throw new ParcelFormatException("File corrupt: too many job timers " + NJ);
14057 for (int ij = 0; ij < NJ; ij++) {
14058 String name = in.readString();
14059 u.readJobSummaryFromParcelLocked(name, in);
14062 u.readJobCompletionsFromParcelLocked(in);
14064 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in);
14065 u.mJobsDeferredCount.readSummaryFromParcelLocked(in);
14066 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in);
14067 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
14068 if (in.readInt() != 0) {
14069 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase);
14070 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in);
14074 int NP = in.readInt();
14076 throw new ParcelFormatException("File corrupt: too many sensors " + NP);
14078 for (int is = 0; is < NP; is++) {
14079 int seNumber = in.readInt();
14080 if (in.readInt() != 0) {
14081 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in);
14087 throw new ParcelFormatException("File corrupt: too many processes " + NP);
14089 for (int ip = 0; ip < NP; ip++) {
14090 String procName = in.readString();
14091 Uid.Proc p = u.getProcessStatsLocked(procName);
14092 p.mUserTime = p.mLoadedUserTime = in.readLong();
14093 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
14094 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
14095 p.mStarts = p.mLoadedStarts = in.readInt();
14096 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt();
14097 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt();
14098 p.readExcessivePowerFromParcelLocked(in);
14103 throw new ParcelFormatException("File corrupt: too many packages " + NP);
14105 for (int ip = 0; ip < NP; ip++) {
14106 String pkgName = in.readString();
14107 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
14108 final int NWA = in.readInt();
14110 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA);
14112 p.mWakeupAlarms.clear();
14113 for (int iwa=0; iwa<NWA; iwa++) {
14114 String tag = in.readString();
14115 Counter c = new Counter(mOnBatteryScreenOffTimeBase);
14116 c.readSummaryFromParcelLocked(in);
14117 p.mWakeupAlarms.put(tag, c);
14121 throw new ParcelFormatException("File corrupt: too many services " + NS);
14123 for (int is = 0; is < NS; is++) {
14124 String servName = in.readString();
14125 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
14126 s.mStartTime = s.mLoadedStartTime = in.readLong();
14127 s.mStarts = s.mLoadedStarts = in.readInt();
14128 s.mLaunches = s.mLoadedLaunches = in.readInt();
14135 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
14136 * disk. This format does not allow a lossless round-trip.
14138 * @param out the Parcel to be written to.
14140 public void writeSummaryToParcel(Parcel out, boolean inclHistory) {
14141 pullPendingStateUpdatesLocked();
14143 // Pull the clock time. This may update the time and make a new history entry
14144 // if we had originally pulled a time before the RTC was set.
14145 long startClockTime = getStartClockTime();
14147 final long NOW_SYS = mClocks.uptimeMillis() * 1000;
14148 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000;
14150 out.writeInt(VERSION);
14152 writeHistory(out, inclHistory, true);
14154 out.writeInt(mStartCount);
14155 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
14156 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
14157 out.writeLong(startClockTime);
14158 out.writeString(mStartPlatformVersion);
14159 out.writeString(mEndPlatformVersion);
14160 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
14161 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
14162 out.writeInt(mDischargeUnplugLevel);
14163 out.writeInt(mDischargePlugLevel);
14164 out.writeInt(mDischargeCurrentLevel);
14165 out.writeInt(mCurrentBatteryLevel);
14166 out.writeInt(mEstimatedBatteryCapacity);
14167 out.writeInt(mMinLearnedBatteryCapacity);
14168 out.writeInt(mMaxLearnedBatteryCapacity);
14169 out.writeInt(getLowDischargeAmountSinceCharge());
14170 out.writeInt(getHighDischargeAmountSinceCharge());
14171 out.writeInt(getDischargeAmountScreenOnSinceCharge());
14172 out.writeInt(getDischargeAmountScreenOffSinceCharge());
14173 out.writeInt(getDischargeAmountScreenDozeSinceCharge());
14174 mDischargeStepTracker.writeToParcel(out);
14175 mChargeStepTracker.writeToParcel(out);
14176 mDailyDischargeStepTracker.writeToParcel(out);
14177 mDailyChargeStepTracker.writeToParcel(out);
14178 mDischargeCounter.writeSummaryFromParcelLocked(out);
14179 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out);
14180 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out);
14181 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out);
14182 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out);
14183 if (mDailyPackageChanges != null) {
14184 final int NPKG = mDailyPackageChanges.size();
14185 out.writeInt(NPKG);
14186 for (int i=0; i<NPKG; i++) {
14187 PackageChange pc = mDailyPackageChanges.get(i);
14188 out.writeString(pc.mPackageName);
14189 out.writeInt(pc.mUpdate ? 1 : 0);
14190 out.writeLong(pc.mVersionCode);
14195 out.writeLong(mDailyStartTime);
14196 out.writeLong(mNextMinDailyDeadline);
14197 out.writeLong(mNextMaxDailyDeadline);
14199 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14200 mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14201 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
14202 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14204 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14205 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14206 out.writeLong(mLongestLightIdleTime);
14207 out.writeLong(mLongestFullIdleTime);
14208 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14209 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14210 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14211 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14212 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14213 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
14214 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14216 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14217 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
14218 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14220 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
14221 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
14222 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
14224 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14225 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14226 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
14227 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
14228 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
14229 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14230 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14231 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14232 for (int i=0; i<NUM_WIFI_STATES; i++) {
14233 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14235 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
14236 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14238 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
14239 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14241 mWifiActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14242 mWifiActivity.writeSummaryToParcel(out);
14243 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
14244 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14246 mBluetoothActivity.writeSummaryToParcel(out);
14247 mModemActivity.writeSummaryToParcel(out);
14248 out.writeInt(mHasWifiReporting ? 1 : 0);
14249 out.writeInt(mHasBluetoothReporting ? 1 : 0);
14250 out.writeInt(mHasModemReporting ? 1 : 0);
14252 out.writeInt(mNumConnectivityChange);
14253 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14254 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14255 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14257 out.writeInt(mRpmStats.size());
14258 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) {
14259 Timer rpmt = ent.getValue();
14260 if (rpmt != null) {
14262 out.writeString(ent.getKey());
14263 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14268 out.writeInt(mScreenOffRpmStats.size());
14269 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) {
14270 Timer rpmt = ent.getValue();
14271 if (rpmt != null) {
14273 out.writeString(ent.getKey());
14274 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14280 out.writeInt(mKernelWakelockStats.size());
14281 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
14282 Timer kwlt = ent.getValue();
14283 if (kwlt != null) {
14285 out.writeString(ent.getKey());
14286 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14292 out.writeInt(mWakeupReasonStats.size());
14293 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
14294 SamplingTimer timer = ent.getValue();
14295 if (timer != null) {
14297 out.writeString(ent.getKey());
14298 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14304 out.writeInt(mKernelMemoryStats.size());
14305 for (int i = 0; i < mKernelMemoryStats.size(); i++) {
14306 Timer kmt = mKernelMemoryStats.valueAt(i);
14309 out.writeLong(mKernelMemoryStats.keyAt(i));
14310 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14316 final int NU = mUidStats.size();
14318 for (int iu = 0; iu < NU; iu++) {
14319 out.writeInt(mUidStats.keyAt(iu));
14320 Uid u = mUidStats.valueAt(iu);
14322 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
14323 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
14325 if (u.mWifiRunningTimer != null) {
14327 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14331 if (u.mFullWifiLockTimer != null) {
14333 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14337 if (u.mWifiScanTimer != null) {
14339 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14343 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
14344 if (u.mWifiBatchedScanTimer[i] != null) {
14346 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14351 if (u.mWifiMulticastTimer != null) {
14353 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14357 if (u.mAudioTurnedOnTimer != null) {
14359 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14363 if (u.mVideoTurnedOnTimer != null) {
14365 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14369 if (u.mFlashlightTurnedOnTimer != null) {
14371 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14375 if (u.mCameraTurnedOnTimer != null) {
14377 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14381 if (u.mForegroundActivityTimer != null) {
14383 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14387 if (u.mForegroundServiceTimer != null) {
14389 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14393 if (u.mAggregatedPartialWakelockTimer != null) {
14395 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14399 if (u.mBluetoothScanTimer != null) {
14401 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14405 if (u.mBluetoothUnoptimizedScanTimer != null) {
14407 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14411 if (u.mBluetoothScanResultCounter != null) {
14413 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out);
14417 if (u.mBluetoothScanResultBgCounter != null) {
14419 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out);
14423 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
14424 if (u.mProcessStateTimer[i] != null) {
14426 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14431 if (u.mVibratorOnTimer != null) {
14433 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14438 if (u.mUserActivityCounters == null) {
14442 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
14443 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
14447 if (u.mNetworkByteActivityCounters == null) {
14451 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
14452 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
14453 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
14455 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
14456 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
14459 u.mUserCpuTime.writeSummaryFromParcelLocked(out);
14460 u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
14462 if (u.mCpuClusterSpeedTimesUs != null) {
14464 out.writeInt(u.mCpuClusterSpeedTimesUs.length);
14465 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) {
14466 if (cpuSpeeds != null) {
14468 out.writeInt(cpuSpeeds.length);
14469 for (LongSamplingCounter c : cpuSpeeds) {
14472 c.writeSummaryFromParcelLocked(out);
14485 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs);
14486 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs);
14488 u.mCpuActiveTimeMs.writeSummaryFromParcelLocked(out);
14489 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out);
14491 if (u.mProcStateTimeMs != null) {
14492 out.writeInt(u.mProcStateTimeMs.length);
14493 for (LongSamplingCounterArray counters : u.mProcStateTimeMs) {
14494 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters);
14499 if (u.mProcStateScreenOffTimeMs != null) {
14500 out.writeInt(u.mProcStateScreenOffTimeMs.length);
14501 for (LongSamplingCounterArray counters : u.mProcStateScreenOffTimeMs) {
14502 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters);
14508 if (u.mMobileRadioApWakeupCount != null) {
14510 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out);
14515 if (u.mWifiRadioApWakeupCount != null) {
14517 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out);
14522 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
14523 int NW = wakeStats.size();
14525 for (int iw=0; iw<NW; iw++) {
14526 out.writeString(wakeStats.keyAt(iw));
14527 Uid.Wakelock wl = wakeStats.valueAt(iw);
14528 if (wl.mTimerFull != null) {
14530 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14534 if (wl.mTimerPartial != null) {
14536 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14540 if (wl.mTimerWindow != null) {
14542 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14546 if (wl.mTimerDraw != null) {
14548 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14554 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap();
14555 int NS = syncStats.size();
14557 for (int is=0; is<NS; is++) {
14558 out.writeString(syncStats.keyAt(is));
14559 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14562 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap();
14563 int NJ = jobStats.size();
14565 for (int ij=0; ij<NJ; ij++) {
14566 out.writeString(jobStats.keyAt(ij));
14567 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14570 u.writeJobCompletionsToParcelLocked(out);
14572 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out);
14573 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out);
14574 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out);
14575 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
14576 if (u.mJobsFreshnessBuckets[i] != null) {
14577 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out);
14583 int NSE = u.mSensorStats.size();
14585 for (int ise=0; ise<NSE; ise++) {
14586 out.writeInt(u.mSensorStats.keyAt(ise));
14587 Uid.Sensor se = u.mSensorStats.valueAt(ise);
14588 if (se.mTimer != null) {
14590 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
14596 int NP = u.mProcessStats.size();
14598 for (int ip=0; ip<NP; ip++) {
14599 out.writeString(u.mProcessStats.keyAt(ip));
14600 Uid.Proc ps = u.mProcessStats.valueAt(ip);
14601 out.writeLong(ps.mUserTime);
14602 out.writeLong(ps.mSystemTime);
14603 out.writeLong(ps.mForegroundTime);
14604 out.writeInt(ps.mStarts);
14605 out.writeInt(ps.mNumCrashes);
14606 out.writeInt(ps.mNumAnrs);
14607 ps.writeExcessivePowerToParcelLocked(out);
14610 NP = u.mPackageStats.size();
14613 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
14614 : u.mPackageStats.entrySet()) {
14615 out.writeString(ent.getKey());
14616 Uid.Pkg ps = ent.getValue();
14617 final int NWA = ps.mWakeupAlarms.size();
14619 for (int iwa=0; iwa<NWA; iwa++) {
14620 out.writeString(ps.mWakeupAlarms.keyAt(iwa));
14621 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out);
14623 NS = ps.mServiceStats.size();
14625 for (int is=0; is<NS; is++) {
14626 out.writeString(ps.mServiceStats.keyAt(is));
14627 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
14628 long time = ss.getStartTimeToNowLocked(
14629 mOnBatteryTimeBase.getUptime(NOW_SYS));
14630 out.writeLong(time);
14631 out.writeInt(ss.mStarts);
14632 out.writeInt(ss.mLaunches);
14639 public void readFromParcel(Parcel in) {
14640 readFromParcelLocked(in);
14643 void readFromParcelLocked(Parcel in) {
14644 int magic = in.readInt();
14645 if (magic != MAGIC) {
14646 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic));
14649 readHistory(in, false);
14651 mStartCount = in.readInt();
14652 mStartClockTime = in.readLong();
14653 mStartPlatformVersion = in.readString();
14654 mEndPlatformVersion = in.readString();
14655 mUptime = in.readLong();
14656 mUptimeStart = in.readLong();
14657 mRealtime = in.readLong();
14658 mRealtimeStart = in.readLong();
14659 mOnBattery = in.readInt() != 0;
14660 mEstimatedBatteryCapacity = in.readInt();
14661 mMinLearnedBatteryCapacity = in.readInt();
14662 mMaxLearnedBatteryCapacity = in.readInt();
14663 mOnBatteryInternal = false; // we are no longer really running.
14664 mOnBatteryTimeBase.readFromParcel(in);
14665 mOnBatteryScreenOffTimeBase.readFromParcel(in);
14667 mScreenState = Display.STATE_UNKNOWN;
14668 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in);
14669 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in);
14670 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
14671 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null,
14672 mOnBatteryTimeBase, in);
14674 mInteractive = false;
14675 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in);
14677 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null,
14678 mOnBatteryTimeBase, in);
14679 mLongestLightIdleTime = in.readLong();
14680 mLongestFullIdleTime = in.readLong();
14681 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null,
14682 mOnBatteryTimeBase, in);
14683 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null,
14684 mOnBatteryTimeBase, in);
14685 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null,
14686 mOnBatteryTimeBase, in);
14687 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in);
14688 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in);
14689 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
14690 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i,
14691 null, mOnBatteryTimeBase, in);
14693 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null,
14694 mOnBatteryTimeBase, in);
14695 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
14696 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i,
14697 null, mOnBatteryTimeBase, in);
14699 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
14700 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
14701 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
14703 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
14704 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null,
14705 mOnBatteryTimeBase, in);
14706 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null,
14707 mOnBatteryTimeBase, in);
14708 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
14709 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
14710 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
14711 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, -4, null,
14712 mOnBatteryTimeBase, in);
14713 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
14715 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in);
14716 mGlobalWifiRunning = false;
14717 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null,
14718 mOnBatteryTimeBase, in);
14719 for (int i=0; i<NUM_WIFI_STATES; i++) {
14720 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i,
14721 null, mOnBatteryTimeBase, in);
14723 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
14724 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i,
14725 null, mOnBatteryTimeBase, in);
14727 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
14728 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i,
14729 null, mOnBatteryTimeBase, in);
14731 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null,
14732 mOnBatteryTimeBase, in);
14733 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
14734 NUM_WIFI_TX_LEVELS, in);
14735 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
14736 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i,
14737 null, mOnBatteryTimeBase, in);
14739 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
14740 NUM_BT_TX_LEVELS, in);
14741 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
14742 ModemActivityInfo.TX_POWER_LEVELS, in);
14743 mHasWifiReporting = in.readInt() != 0;
14744 mHasBluetoothReporting = in.readInt() != 0;
14745 mHasModemReporting = in.readInt() != 0;
14747 mNumConnectivityChange = in.readInt();
14748 mLoadedNumConnectivityChange = in.readInt();
14749 mUnpluggedNumConnectivityChange = in.readInt();
14750 mAudioOnNesting = 0;
14751 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase);
14752 mVideoOnNesting = 0;
14753 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase);
14754 mFlashlightOnNesting = 0;
14755 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in);
14756 mCameraOnNesting = 0;
14757 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in);
14758 mBluetoothScanNesting = 0;
14759 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in);
14760 mIsCellularTxPowerHigh = false;
14761 mDischargeUnplugLevel = in.readInt();
14762 mDischargePlugLevel = in.readInt();
14763 mDischargeCurrentLevel = in.readInt();
14764 mCurrentBatteryLevel = in.readInt();
14765 mLowDischargeAmountSinceCharge = in.readInt();
14766 mHighDischargeAmountSinceCharge = in.readInt();
14767 mDischargeAmountScreenOn = in.readInt();
14768 mDischargeAmountScreenOnSinceCharge = in.readInt();
14769 mDischargeAmountScreenOff = in.readInt();
14770 mDischargeAmountScreenOffSinceCharge = in.readInt();
14771 mDischargeAmountScreenDoze = in.readInt();
14772 mDischargeAmountScreenDozeSinceCharge = in.readInt();
14773 mDischargeStepTracker.readFromParcel(in);
14774 mChargeStepTracker.readFromParcel(in);
14775 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
14776 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in);
14777 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
14778 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
14779 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
14780 mLastWriteTime = in.readLong();
14783 int NRPMS = in.readInt();
14784 for (int irpm = 0; irpm < NRPMS; irpm++) {
14785 if (in.readInt() != 0) {
14786 String rpmName = in.readString();
14787 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in);
14788 mRpmStats.put(rpmName, rpmt);
14791 mScreenOffRpmStats.clear();
14792 int NSORPMS = in.readInt();
14793 for (int irpm = 0; irpm < NSORPMS; irpm++) {
14794 if (in.readInt() != 0) {
14795 String rpmName = in.readString();
14796 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in);
14797 mScreenOffRpmStats.put(rpmName, rpmt);
14801 mKernelWakelockStats.clear();
14802 int NKW = in.readInt();
14803 for (int ikw = 0; ikw < NKW; ikw++) {
14804 if (in.readInt() != 0) {
14805 String wakelockName = in.readString();
14806 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in);
14807 mKernelWakelockStats.put(wakelockName, kwlt);
14811 mWakeupReasonStats.clear();
14812 int NWR = in.readInt();
14813 for (int iwr = 0; iwr < NWR; iwr++) {
14814 if (in.readInt() != 0) {
14815 String reasonName = in.readString();
14816 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in);
14817 mWakeupReasonStats.put(reasonName, timer);
14821 mKernelMemoryStats.clear();
14822 int nmt = in.readInt();
14823 for (int imt = 0; imt < nmt; imt++) {
14824 if (in.readInt() != 0) {
14825 Long bucket = in.readLong();
14826 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in);
14827 mKernelMemoryStats.put(bucket, kmt);
14831 mPartialTimers.clear();
14832 mFullTimers.clear();
14833 mWindowTimers.clear();
14834 mWifiRunningTimers.clear();
14835 mFullWifiLockTimers.clear();
14836 mWifiScanTimers.clear();
14837 mWifiBatchedScanTimers.clear();
14838 mWifiMulticastTimers.clear();
14839 mAudioTurnedOnTimers.clear();
14840 mVideoTurnedOnTimers.clear();
14841 mFlashlightTurnedOnTimers.clear();
14842 mCameraTurnedOnTimers.clear();
14844 int numUids = in.readInt();
14846 for (int i = 0; i < numUids; i++) {
14847 int uid = in.readInt();
14848 Uid u = new Uid(this, uid);
14849 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
14850 mUidStats.append(uid, u);
14854 public void writeToParcel(Parcel out, int flags) {
14855 writeToParcelLocked(out, true, flags);
14858 public void writeToParcelWithoutUids(Parcel out, int flags) {
14859 writeToParcelLocked(out, false, flags);
14862 @SuppressWarnings("unused")
14863 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
14864 // Need to update with current kernel wake lock counts.
14865 pullPendingStateUpdatesLocked();
14867 // Pull the clock time. This may update the time and make a new history entry
14868 // if we had originally pulled a time before the RTC was set.
14869 long startClockTime = getStartClockTime();
14871 final long uSecUptime = mClocks.uptimeMillis() * 1000;
14872 final long uSecRealtime = mClocks.elapsedRealtime() * 1000;
14873 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
14874 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
14876 out.writeInt(MAGIC);
14878 writeHistory(out, true, false);
14880 out.writeInt(mStartCount);
14881 out.writeLong(startClockTime);
14882 out.writeString(mStartPlatformVersion);
14883 out.writeString(mEndPlatformVersion);
14884 out.writeLong(mUptime);
14885 out.writeLong(mUptimeStart);
14886 out.writeLong(mRealtime);
14887 out.writeLong(mRealtimeStart);
14888 out.writeInt(mOnBattery ? 1 : 0);
14889 out.writeInt(mEstimatedBatteryCapacity);
14890 out.writeInt(mMinLearnedBatteryCapacity);
14891 out.writeInt(mMaxLearnedBatteryCapacity);
14892 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
14893 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
14895 mScreenOnTimer.writeToParcel(out, uSecRealtime);
14896 mScreenDozeTimer.writeToParcel(out, uSecRealtime);
14897 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
14898 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
14900 mInteractiveTimer.writeToParcel(out, uSecRealtime);
14901 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime);
14902 out.writeLong(mLongestLightIdleTime);
14903 out.writeLong(mLongestFullIdleTime);
14904 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime);
14905 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime);
14906 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime);
14907 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime);
14908 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
14909 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
14910 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
14912 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
14913 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
14914 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
14916 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
14917 mNetworkByteActivityCounters[i].writeToParcel(out);
14918 mNetworkPacketActivityCounters[i].writeToParcel(out);
14920 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
14921 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
14922 mMobileRadioActiveAdjustedTime.writeToParcel(out);
14923 mMobileRadioActiveUnknownTime.writeToParcel(out);
14924 mMobileRadioActiveUnknownCount.writeToParcel(out);
14925 mWifiMulticastWakelockTimer.writeToParcel(out, uSecRealtime);
14926 mWifiOnTimer.writeToParcel(out, uSecRealtime);
14927 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
14928 for (int i=0; i<NUM_WIFI_STATES; i++) {
14929 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
14931 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
14932 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime);
14934 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
14935 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
14937 mWifiActiveTimer.writeToParcel(out, uSecRealtime);
14938 mWifiActivity.writeToParcel(out, 0);
14939 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
14940 mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime);
14942 mBluetoothActivity.writeToParcel(out, 0);
14943 mModemActivity.writeToParcel(out, 0);
14944 out.writeInt(mHasWifiReporting ? 1 : 0);
14945 out.writeInt(mHasBluetoothReporting ? 1 : 0);
14946 out.writeInt(mHasModemReporting ? 1 : 0);
14948 out.writeInt(mNumConnectivityChange);
14949 out.writeInt(mLoadedNumConnectivityChange);
14950 out.writeInt(mUnpluggedNumConnectivityChange);
14951 mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
14952 mCameraOnTimer.writeToParcel(out, uSecRealtime);
14953 mBluetoothScanTimer.writeToParcel(out, uSecRealtime);
14954 out.writeInt(mDischargeUnplugLevel);
14955 out.writeInt(mDischargePlugLevel);
14956 out.writeInt(mDischargeCurrentLevel);
14957 out.writeInt(mCurrentBatteryLevel);
14958 out.writeInt(mLowDischargeAmountSinceCharge);
14959 out.writeInt(mHighDischargeAmountSinceCharge);
14960 out.writeInt(mDischargeAmountScreenOn);
14961 out.writeInt(mDischargeAmountScreenOnSinceCharge);
14962 out.writeInt(mDischargeAmountScreenOff);
14963 out.writeInt(mDischargeAmountScreenOffSinceCharge);
14964 out.writeInt(mDischargeAmountScreenDoze);
14965 out.writeInt(mDischargeAmountScreenDozeSinceCharge);
14966 mDischargeStepTracker.writeToParcel(out);
14967 mChargeStepTracker.writeToParcel(out);
14968 mDischargeCounter.writeToParcel(out);
14969 mDischargeScreenOffCounter.writeToParcel(out);
14970 mDischargeScreenDozeCounter.writeToParcel(out);
14971 mDischargeLightDozeCounter.writeToParcel(out);
14972 mDischargeDeepDozeCounter.writeToParcel(out);
14973 out.writeLong(mLastWriteTime);
14975 out.writeInt(mRpmStats.size());
14976 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) {
14977 SamplingTimer rpmt = ent.getValue();
14978 if (rpmt != null) {
14980 out.writeString(ent.getKey());
14981 rpmt.writeToParcel(out, uSecRealtime);
14986 out.writeInt(mScreenOffRpmStats.size());
14987 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) {
14988 SamplingTimer rpmt = ent.getValue();
14989 if (rpmt != null) {
14991 out.writeString(ent.getKey());
14992 rpmt.writeToParcel(out, uSecRealtime);
14999 out.writeInt(mKernelWakelockStats.size());
15000 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
15001 SamplingTimer kwlt = ent.getValue();
15002 if (kwlt != null) {
15004 out.writeString(ent.getKey());
15005 kwlt.writeToParcel(out, uSecRealtime);
15010 out.writeInt(mWakeupReasonStats.size());
15011 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
15012 SamplingTimer timer = ent.getValue();
15013 if (timer != null) {
15015 out.writeString(ent.getKey());
15016 timer.writeToParcel(out, uSecRealtime);
15026 out.writeInt(mKernelMemoryStats.size());
15027 for (int i = 0; i < mKernelMemoryStats.size(); i++) {
15028 SamplingTimer kmt = mKernelMemoryStats.valueAt(i);
15031 out.writeLong(mKernelMemoryStats.keyAt(i));
15032 kmt.writeToParcel(out, uSecRealtime);
15039 int size = mUidStats.size();
15040 out.writeInt(size);
15041 for (int i = 0; i < size; i++) {
15042 out.writeInt(mUidStats.keyAt(i));
15043 Uid uid = mUidStats.valueAt(i);
15045 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime);
15052 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
15053 new Parcelable.Creator<BatteryStatsImpl>() {
15054 public BatteryStatsImpl createFromParcel(Parcel in) {
15055 return new BatteryStatsImpl(in);
15058 public BatteryStatsImpl[] newArray(int size) {
15059 return new BatteryStatsImpl[size];
15063 public void prepareForDumpLocked() {
15064 // Need to retrieve current kernel wake lock stats before printing.
15065 pullPendingStateUpdatesLocked();
15067 // Pull the clock time. This may update the time and make a new history entry
15068 // if we had originally pulled a time before the RTC was set.
15069 getStartClockTime();
15072 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
15074 pw.println("mOnBatteryTimeBase:");
15075 mOnBatteryTimeBase.dump(pw, " ");
15076 pw.println("mOnBatteryScreenOffTimeBase:");
15077 mOnBatteryScreenOffTimeBase.dump(pw, " ");
15078 Printer pr = new PrintWriterPrinter(pw);
15079 pr.println("*** Screen on timer:");
15080 mScreenOnTimer.logState(pr, " ");
15081 pr.println("*** Screen doze timer:");
15082 mScreenDozeTimer.logState(pr, " ");
15083 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
15084 pr.println("*** Screen brightness #" + i + ":");
15085 mScreenBrightnessTimer[i].logState(pr, " ");
15087 pr.println("*** Interactive timer:");
15088 mInteractiveTimer.logState(pr, " ");
15089 pr.println("*** Power save mode timer:");
15090 mPowerSaveModeEnabledTimer.logState(pr, " ");
15091 pr.println("*** Device idle mode light timer:");
15092 mDeviceIdleModeLightTimer.logState(pr, " ");
15093 pr.println("*** Device idle mode full timer:");
15094 mDeviceIdleModeFullTimer.logState(pr, " ");
15095 pr.println("*** Device light idling timer:");
15096 mDeviceLightIdlingTimer.logState(pr, " ");
15097 pr.println("*** Device idling timer:");
15098 mDeviceIdlingTimer.logState(pr, " ");
15099 pr.println("*** Phone timer:");
15100 mPhoneOnTimer.logState(pr, " ");
15101 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
15102 pr.println("*** Phone signal strength #" + i + ":");
15103 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
15105 pr.println("*** Signal scanning :");
15106 mPhoneSignalScanningTimer.logState(pr, " ");
15107 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
15108 pr.println("*** Data connection type #" + i + ":");
15109 mPhoneDataConnectionsTimer[i].logState(pr, " ");
15111 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState);
15112 pr.println("*** Mobile network active timer:");
15113 mMobileRadioActiveTimer.logState(pr, " ");
15114 pr.println("*** Mobile network active adjusted timer:");
15115 mMobileRadioActiveAdjustedTime.logState(pr, " ");
15116 pr.println("*** Wifi Multicast WakeLock Timer:");
15117 mWifiMulticastWakelockTimer.logState(pr, " ");
15118 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState);
15119 pr.println("*** Wifi timer:");
15120 mWifiOnTimer.logState(pr, " ");
15121 pr.println("*** WifiRunning timer:");
15122 mGlobalWifiRunningTimer.logState(pr, " ");
15123 for (int i=0; i<NUM_WIFI_STATES; i++) {
15124 pr.println("*** Wifi state #" + i + ":");
15125 mWifiStateTimer[i].logState(pr, " ");
15127 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
15128 pr.println("*** Wifi suppl state #" + i + ":");
15129 mWifiSupplStateTimer[i].logState(pr, " ");
15131 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
15132 pr.println("*** Wifi signal strength #" + i + ":");
15133 mWifiSignalStrengthsTimer[i].logState(pr, " ");
15135 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
15136 pr.println("*** GPS signal quality #" + i + ":");
15137 mGpsSignalQualityTimer[i].logState(pr, " ");
15139 pr.println("*** Flashlight timer:");
15140 mFlashlightOnTimer.logState(pr, " ");
15141 pr.println("*** Camera timer:");
15142 mCameraOnTimer.logState(pr, " ");
15144 super.dumpLocked(context, pw, flags, reqUid, histStart);
15145 pw.print("Total cpu time reads: ");
15146 pw.println(mNumCpuTimeReads);
15147 pw.print("Batched cpu time reads: ");
15148 pw.println(mNumBatchedCpuTimeReads);
15149 pw.print("Batching Duration (min): ");
15150 pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTime) / (60 * 1000));