blob: 405c861a498a8027420f1727c94dae71839ea453 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2007 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17package com.android.internal.os;
18
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070019import android.annotation.Nullable;
Dianne Hackborn61659e52014-07-09 16:13:01 -070020import android.app.ActivityManager;
Adam Lesinski33dac552015-03-09 15:24:48 -070021import android.bluetooth.BluetoothActivityEnergyInfo;
Dianne Hackborna7c837f2014-01-15 16:20:44 -080022import android.content.Context;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070023import android.content.Intent;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070024import android.net.ConnectivityManager;
25import android.net.NetworkStats;
Adam Lesinski33dac552015-03-09 15:24:48 -070026import android.net.wifi.WifiActivityEnergyInfo;
Dianne Hackborn3251b902014-06-20 14:40:53 -070027import android.net.wifi.WifiManager;
Dianne Hackborn00e25212014-02-19 10:49:24 -080028import android.os.BadParcelableException;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070029import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.os.BatteryStats;
Dianne Hackborncd0e3352014-08-07 17:08:09 -070031import android.os.Build;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070032import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070033import android.os.Handler;
Jeff Brown6f357d32014-01-15 20:40:55 -080034import android.os.Looper;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070035import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.os.Parcel;
37import android.os.ParcelFormatException;
38import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070039import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.os.SystemClock;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080041import android.os.SystemProperties;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070042import android.os.WorkSource;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070043import android.telephony.DataConnectionRealTimeInfo;
Amith Yamasanif37447b2009-10-08 18:28:01 -070044import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070045import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070046import android.telephony.TelephonyManager;
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -070047import android.text.TextUtils;
Dianne Hackborn61659e52014-07-09 16:13:01 -070048import android.util.ArrayMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070050import android.util.LogWriter;
Dianne Hackbornd953c532014-08-16 18:17:38 -070051import android.util.MutableInt;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070052import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070054import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.util.SparseArray;
Dianne Hackborn099bc622014-01-22 13:39:16 -080056import android.util.SparseIntArray;
Adam Lesinskie08af192015-03-25 16:42:59 -070057import android.util.SparseLongArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070058import android.util.TimeUtils;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080059import android.util.Xml;
Jeff Browne95c3cd2014-05-02 16:59:26 -070060import android.view.Display;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070062import com.android.internal.net.NetworkStatsFactory;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080063import com.android.internal.util.ArrayUtils;
Dianne Hackborn8c841092013-06-24 13:46:13 -070064import com.android.internal.util.FastPrintWriter;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080065import com.android.internal.util.FastXmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070066import com.android.internal.util.JournaledFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080067import com.android.internal.util.XmlUtils;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070068import com.android.server.NetworkManagementSocketTagger;
69import libcore.util.EmptyArray;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080070import org.xmlpull.v1.XmlPullParser;
71import org.xmlpull.v1.XmlPullParserException;
72import org.xmlpull.v1.XmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070073
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080074import java.io.ByteArrayOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import java.io.File;
76import java.io.FileInputStream;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080077import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import java.io.FileOutputStream;
79import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070080import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import java.util.ArrayList;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080082import java.util.Calendar;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070084import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070086import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070087import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
89/**
90 * All information we are collecting about things that can happen that impact
91 * battery life. All times are represented in microseconds except where indicated
92 * otherwise.
93 */
94public final class BatteryStatsImpl extends BatteryStats {
95 private static final String TAG = "BatteryStatsImpl";
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080096 private static final boolean DEBUG = false;
Adam Lesinskie08af192015-03-25 16:42:59 -070097 private static final boolean DEBUG_ENERGY = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070098 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -070099 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700100
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700101 // TODO: remove "tcp" from network methods, since we measure total stats.
102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700104 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105
106 // Current on-disk Parcel version
Adam Lesinskie283d332015-04-16 12:29:25 -0700107 private static final int VERSION = 125 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700108
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700109 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700110 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700111
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700112 // No, really, THIS is the maximum number of items we will record in the history.
113 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
114
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800115 // The maximum number of names wakelocks we will keep track of
116 // per uid; once the limit is reached, we batch the remaining wakelocks
117 // in to one common name.
Dianne Hackbornacc4a122014-08-18 16:33:44 -0700118 private static final int MAX_WAKELOCKS_PER_UID = 100;
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700119
Amith Yamasanie43530a2009-08-21 13:11:37 -0700120 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700122 private final JournaledFile mFile;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700123 public final AtomicFile mCheckinFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800124 public final AtomicFile mDailyFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700126 static final int MSG_UPDATE_WAKELOCKS = 1;
127 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700128 static final int MSG_REPORT_CHARGING = 3;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700129 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700130
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700131 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
132 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
133
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700134 public interface BatteryCallback {
135 public void batteryNeedsCpuUpdate();
136 public void batteryPowerChanged(boolean onBattery);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700137 public void batterySendBroadcast(Intent intent);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700138 }
139
140 final class MyHandler extends Handler {
Jeff Brown6f357d32014-01-15 20:40:55 -0800141 public MyHandler(Looper looper) {
142 super(looper, null, true);
143 }
144
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700145 @Override
146 public void handleMessage(Message msg) {
147 BatteryCallback cb = mCallback;
148 switch (msg.what) {
149 case MSG_UPDATE_WAKELOCKS:
150 if (cb != null) {
151 cb.batteryNeedsCpuUpdate();
152 }
153 break;
154 case MSG_REPORT_POWER_CHANGE:
155 if (cb != null) {
156 cb.batteryPowerChanged(msg.arg1 != 0);
157 }
158 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700159 case MSG_REPORT_CHARGING:
160 if (cb != null) {
161 final String action;
162 synchronized (BatteryStatsImpl.this) {
163 action = mCharging ? BatteryManager.ACTION_CHARGING
164 : BatteryManager.ACTION_DISCHARGING;
165 }
166 Intent intent = new Intent(action);
167 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
168 cb.batterySendBroadcast(intent);
169 }
170 break;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700171 }
172 }
173 }
174
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700175 public interface ExternalStatsSync {
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700176 void scheduleSync(String reason);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700177 }
178
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700179 public final MyHandler mHandler;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700180 private final ExternalStatsSync mExternalSync;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700181
182 private BatteryCallback mCallback;
183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -0800185 * Mapping isolated uids to the actual owning app uid.
186 */
187 final SparseIntArray mIsolatedUids = new SparseIntArray();
188
189 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 * The statistics we have collected organized by uids.
191 */
192 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
193 new SparseArray<BatteryStatsImpl.Uid>();
194
195 // A set of pools of currently active timers. When a timer is queried, we will divide the
196 // elapsed time by the number of active timers to arrive at that timer's share of the time.
197 // In order to do this, we must refresh each timer whenever the number of active timers
198 // changes.
Adam Lesinskie08af192015-03-25 16:42:59 -0700199 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
200 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
201 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
202 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
203 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
204 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
205 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
206 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
207 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
208 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
209 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700211 // Last partial timers we use for distributing CPU usage.
Adam Lesinskie08af192015-03-25 16:42:59 -0700212 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 // These are the objects that will want to do something when the device
215 // is unplugged from power.
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800216 final TimeBase mOnBatteryTimeBase = new TimeBase();
217
218 // These are the objects that will want to do something when the device
219 // is unplugged from power *and* the screen is off.
220 final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
221
222 // Set to true when we want to distribute CPU across wakelocks for the next
223 // CPU update, even if we aren't currently running wake locks.
224 boolean mDistributeWakelockCpu;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700225
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700226 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700227
Dianne Hackborn37de0982014-05-09 09:32:18 -0700228 final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800229
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700230 long mHistoryBaseTime;
231 boolean mHaveBatteryLevel = false;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700232 boolean mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700233 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700234
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700235 static final int MAX_HISTORY_BUFFER = 256*1024; // 256KB
236 static final int MAX_MAX_HISTORY_BUFFER = 320*1024; // 320KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700237 final Parcel mHistoryBuffer = Parcel.obtain();
238 final HistoryItem mHistoryLastWritten = new HistoryItem();
239 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700240 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700241 final HistoryItem mHistoryAddTmp = new HistoryItem();
Adam Lesinskie08af192015-03-25 16:42:59 -0700242 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
Dianne Hackborn099bc622014-01-22 13:39:16 -0800243 String[] mReadHistoryStrings;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800244 int[] mReadHistoryUids;
245 int mReadHistoryChars;
246 int mNextHistoryTagIdx = 0;
247 int mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700248 int mHistoryBufferLastPos = -1;
249 boolean mHistoryOverflow = false;
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700250 int mActiveHistoryStates = 0xffffffff;
251 int mActiveHistoryStates2 = 0xffffffff;
Dianne Hackborn40c87252014-03-19 16:55:40 -0700252 long mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700253 long mTrackRunningHistoryElapsedRealtime = 0;
254 long mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700255
256 final HistoryItem mHistoryCur = new HistoryItem();
257
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700258 HistoryItem mHistory;
259 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700260 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700261 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700262
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800263 // Used by computeHistoryStepDetails
264 HistoryStepDetails mLastHistoryStepDetails = null;
265 byte mLastHistoryStepLevel = 0;
266 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
267 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails();
268 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
269 /**
270 * Total time (in 1/100 sec) spent executing in user code.
271 */
272 long mLastStepCpuUserTime;
273 long mCurStepCpuUserTime;
274 /**
275 * Total time (in 1/100 sec) spent executing in kernel code.
276 */
277 long mLastStepCpuSystemTime;
278 long mCurStepCpuSystemTime;
279 /**
280 * Times from /proc/stat
281 */
282 long mLastStepStatUserTime;
283 long mLastStepStatSystemTime;
284 long mLastStepStatIOWaitTime;
285 long mLastStepStatIrqTime;
286 long mLastStepStatSoftIrqTime;
287 long mLastStepStatIdleTime;
288 long mCurStepStatUserTime;
289 long mCurStepStatSystemTime;
290 long mCurStepStatIOWaitTime;
291 long mCurStepStatIrqTime;
292 long mCurStepStatSoftIrqTime;
293 long mCurStepStatIdleTime;
294
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700295 private HistoryItem mHistoryIterator;
296 private boolean mReadOverflow;
297 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 int mStartCount;
300
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800301 long mStartClockTime;
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700302 String mStartPlatformVersion;
303 String mEndPlatformVersion;
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800304
Dianne Hackborna7d0d552014-09-12 17:15:52 -0700305 long mLastRecordedClockTime;
306 long mLastRecordedClockRealtime;
307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 long mUptime;
309 long mUptimeStart;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 long mRealtime;
311 long mRealtimeStart;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700312
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800313 int mWakeLockNesting;
314 boolean mWakeLockImportant;
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700315 public boolean mRecordAllHistory;
Dianne Hackborn9a755432014-05-15 17:05:22 -0700316 boolean mNoAutoReset;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800317
Jeff Browne95c3cd2014-05-02 16:59:26 -0700318 int mScreenState = Display.STATE_UNKNOWN;
Evan Millarc64edde2009-04-18 12:26:32 -0700319 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700320
Dianne Hackborn617f8772009-03-31 15:04:46 -0700321 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700322 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700323
Jeff Browne95c3cd2014-05-02 16:59:26 -0700324 boolean mInteractive;
325 StopwatchTimer mInteractiveTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700326
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700327 boolean mPowerSaveModeEnabled;
328 StopwatchTimer mPowerSaveModeEnabledTimer;
329
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700330 boolean mDeviceIdling;
331 StopwatchTimer mDeviceIdlingTimer;
332
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700333 boolean mDeviceIdleModeEnabled;
334 StopwatchTimer mDeviceIdleModeEnabledTimer;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700337 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700338
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700339 int mAudioOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700340 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700341
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700342 int mVideoOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700343 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700344
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700345 boolean mFlashlightOn;
346 StopwatchTimer mFlashlightOnTimer;
347
Dianne Hackborn627bba72009-03-24 22:32:56 -0700348 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800349 int mPhoneSignalStrengthBinRaw = -1;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700350 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800351 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700352
353 StopwatchTimer mPhoneSignalScanningTimer;
354
Dianne Hackborn627bba72009-03-24 22:32:56 -0700355 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700356 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700357 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700358
Dianne Hackborn57ed6a62013-12-09 18:15:56 -0800359 final LongSamplingCounter[] mNetworkByteActivityCounters =
360 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
361 final LongSamplingCounter[] mNetworkPacketActivityCounters =
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700362 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
363
Adam Lesinski33dac552015-03-09 15:24:48 -0700364 final LongSamplingCounter[] mBluetoothActivityCounters =
365 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
366
367 final LongSamplingCounter[] mWifiActivityCounters =
368 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
369
The Android Open Source Project10592532009-03-18 17:39:46 -0700370 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700371 StopwatchTimer mWifiOnTimer;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700372
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700373 boolean mGlobalWifiRunning;
374 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700375
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800376 int mWifiState = -1;
377 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
378
Dianne Hackborn3251b902014-06-20 14:40:53 -0700379 int mWifiSupplState = -1;
380 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES];
381
382 int mWifiSignalStrengthBin = -1;
383 final StopwatchTimer[] mWifiSignalStrengthsTimer =
384 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS];
385
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700386 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackbornf7097a52014-05-13 09:56:14 -0700387 long mMobileRadioActiveStartTime;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800388 StopwatchTimer mMobileRadioActiveTimer;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800389 StopwatchTimer mMobileRadioActivePerAppTimer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700390 LongSamplingCounter mMobileRadioActiveAdjustedTime;
Dianne Hackbornd45665b2014-02-26 12:35:32 -0800391 LongSamplingCounter mMobileRadioActiveUnknownTime;
392 LongSamplingCounter mMobileRadioActiveUnknownCount;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800393
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700394 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 /**
397 * These provide time bases that discount the time the device is plugged
398 * in to power.
399 */
400 boolean mOnBattery;
401 boolean mOnBatteryInternal;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700402
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700403 /**
404 * External reporting of whether the device is actually charging.
405 */
406 boolean mCharging = true;
407 int mLastChargingStateLevel;
408
The Android Open Source Project10592532009-03-18 17:39:46 -0700409 /*
410 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
411 */
Evan Millar633a1742009-04-02 16:36:33 -0700412 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700413 int mDischargeUnplugLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700414 int mDischargePlugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700415 int mDischargeCurrentLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700416 int mCurrentBatteryLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700417 int mLowDischargeAmountSinceCharge;
418 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800419 int mDischargeScreenOnUnplugLevel;
420 int mDischargeScreenOffUnplugLevel;
421 int mDischargeAmountScreenOn;
422 int mDischargeAmountScreenOnSinceCharge;
423 int mDischargeAmountScreenOff;
424 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700425
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700426 static final int MAX_LEVEL_STEPS = 200;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700427
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700428 int mInitStepMode = 0;
429 int mCurStepMode = 0;
430 int mModStepMode = 0;
431
Dianne Hackborn260c5022014-04-29 11:23:16 -0700432 int mLastDischargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700433 int mMinDischargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800434 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
435 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700436 ArrayList<PackageChange> mDailyPackageChanges;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700437
438 int mLastChargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700439 int mMaxChargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800440 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
441 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
442
443 static final int MAX_DAILY_ITEMS = 10;
444
445 long mDailyStartTime = 0;
446 long mNextMinDailyDeadline = 0;
447 long mNextMaxDailyDeadline = 0;
448
449 final ArrayList<DailyItem> mDailyItems = new ArrayList<>();
Dianne Hackborn260c5022014-04-29 11:23:16 -0700450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700452
Amith Yamasanif37447b2009-10-08 18:28:01 -0700453 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800454 private int mPhoneServiceStateRaw = -1;
455 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700456
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800457 private int mNumConnectivityChange;
458 private int mLoadedNumConnectivityChange;
459 private int mUnpluggedNumConnectivityChange;
460
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700461 private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
462
Adam Lesinskie08af192015-03-25 16:42:59 -0700463 private PowerProfile mPowerProfile;
Adam Lesinski17390762015-04-10 13:17:47 -0700464 private boolean mHasWifiEnergyReporting = false;
465 private boolean mHasBluetoothEnergyReporting = false;
Adam Lesinskie08af192015-03-25 16:42:59 -0700466
Evan Millarc64edde2009-04-18 12:26:32 -0700467 /*
468 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
469 */
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700470 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700471
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700472 public Map<String, ? extends Timer> getKernelWakelockStats() {
Evan Millarc64edde2009-04-18 12:26:32 -0700473 return mKernelWakelockStats;
474 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700475
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700476 String mLastWakeupReason = null;
477 long mLastWakeupUptimeMs = 0;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700478 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700479
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700480 public Map<String, ? extends Timer> getWakeupReasonStats() {
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700481 return mWakeupReasonStats;
482 }
483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700485 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700486 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800487 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700488 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700489 mExternalSync = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700490 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 }
492
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800493 public static interface TimeBaseObs {
494 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
495 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
496 }
497
498 static class TimeBase {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700499 private final ArrayList<TimeBaseObs> mObservers = new ArrayList<>();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800500
501 private long mUptime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800502 private long mRealtime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800503
504 private boolean mRunning;
505
506 private long mPastUptime;
507 private long mUptimeStart;
508 private long mPastRealtime;
509 private long mRealtimeStart;
510 private long mUnpluggedUptime;
511 private long mUnpluggedRealtime;
512
513 public void dump(PrintWriter pw, String prefix) {
514 StringBuilder sb = new StringBuilder(128);
515 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
516 sb.setLength(0);
517 sb.append(prefix);
518 sb.append("mUptime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700519 formatTimeMs(sb, mUptime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800520 pw.println(sb.toString());
521 sb.setLength(0);
522 sb.append(prefix);
523 sb.append("mRealtime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700524 formatTimeMs(sb, mRealtime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800525 pw.println(sb.toString());
526 sb.setLength(0);
527 sb.append(prefix);
528 sb.append("mPastUptime=");
529 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
530 formatTimeMs(sb, mUptimeStart / 1000);
531 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
532 pw.println(sb.toString());
533 sb.setLength(0);
534 sb.append(prefix);
535 sb.append("mPastRealtime=");
536 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
537 formatTimeMs(sb, mRealtimeStart / 1000);
538 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
539 pw.println(sb.toString());
540 }
541
542 public void add(TimeBaseObs observer) {
543 mObservers.add(observer);
544 }
545
546 public void remove(TimeBaseObs observer) {
547 if (!mObservers.remove(observer)) {
548 Slog.wtf(TAG, "Removed unknown observer: " + observer);
549 }
550 }
551
552 public void init(long uptime, long realtime) {
553 mRealtime = 0;
554 mUptime = 0;
555 mPastUptime = 0;
556 mPastRealtime = 0;
557 mUptimeStart = uptime;
558 mRealtimeStart = realtime;
559 mUnpluggedUptime = getUptime(mUptimeStart);
560 mUnpluggedRealtime = getRealtime(mRealtimeStart);
561 }
562
563 public void reset(long uptime, long realtime) {
564 if (!mRunning) {
565 mPastUptime = 0;
566 mPastRealtime = 0;
567 } else {
568 mUptimeStart = uptime;
569 mRealtimeStart = realtime;
570 mUnpluggedUptime = getUptime(uptime);
571 mUnpluggedRealtime = getRealtime(realtime);
572 }
573 }
574
575 public long computeUptime(long curTime, int which) {
576 switch (which) {
577 case STATS_SINCE_CHARGED:
578 return mUptime + getUptime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800579 case STATS_CURRENT:
580 return getUptime(curTime);
581 case STATS_SINCE_UNPLUGGED:
582 return getUptime(curTime) - mUnpluggedUptime;
583 }
584 return 0;
585 }
586
587 public long computeRealtime(long curTime, int which) {
588 switch (which) {
589 case STATS_SINCE_CHARGED:
590 return mRealtime + getRealtime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800591 case STATS_CURRENT:
592 return getRealtime(curTime);
593 case STATS_SINCE_UNPLUGGED:
594 return getRealtime(curTime) - mUnpluggedRealtime;
595 }
596 return 0;
597 }
598
599 public long getUptime(long curTime) {
600 long time = mPastUptime;
601 if (mRunning) {
602 time += curTime - mUptimeStart;
603 }
604 return time;
605 }
606
607 public long getRealtime(long curTime) {
608 long time = mPastRealtime;
609 if (mRunning) {
610 time += curTime - mRealtimeStart;
611 }
612 return time;
613 }
614
615 public long getUptimeStart() {
616 return mUptimeStart;
617 }
618
619 public long getRealtimeStart() {
620 return mRealtimeStart;
621 }
622
623 public boolean isRunning() {
624 return mRunning;
625 }
626
627 public boolean setRunning(boolean running, long uptime, long realtime) {
628 if (mRunning != running) {
629 mRunning = running;
630 if (running) {
631 mUptimeStart = uptime;
632 mRealtimeStart = realtime;
633 long batteryUptime = mUnpluggedUptime = getUptime(uptime);
634 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
635
636 for (int i = mObservers.size() - 1; i >= 0; i--) {
637 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
638 }
639 } else {
640 mPastUptime += uptime - mUptimeStart;
641 mPastRealtime += realtime - mRealtimeStart;
642
643 long batteryUptime = getUptime(uptime);
644 long batteryRealtime = getRealtime(realtime);
645
646 for (int i = mObservers.size() - 1; i >= 0; i--) {
647 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
648 }
649 }
650 return true;
651 }
652 return false;
653 }
654
655 public void readSummaryFromParcel(Parcel in) {
656 mUptime = in.readLong();
657 mRealtime = in.readLong();
658 }
659
660 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
661 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
662 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
663 }
664
665 public void readFromParcel(Parcel in) {
666 mRunning = false;
667 mUptime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800668 mPastUptime = in.readLong();
669 mUptimeStart = in.readLong();
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700670 mRealtime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800671 mPastRealtime = in.readLong();
672 mRealtimeStart = in.readLong();
673 mUnpluggedUptime = in.readLong();
674 mUnpluggedRealtime = in.readLong();
675 }
676
677 public void writeToParcel(Parcel out, long uptime, long realtime) {
678 final long runningUptime = getUptime(uptime);
679 final long runningRealtime = getRealtime(realtime);
680 out.writeLong(mUptime);
681 out.writeLong(runningUptime);
682 out.writeLong(mUptimeStart);
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700683 out.writeLong(mRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800684 out.writeLong(runningRealtime);
685 out.writeLong(mRealtimeStart);
686 out.writeLong(mUnpluggedUptime);
687 out.writeLong(mUnpluggedRealtime);
688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700692 * State for keeping track of counting information.
693 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800694 public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
Christopher Tate4cee7252010-03-19 14:50:40 -0700695 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800696 final TimeBase mTimeBase;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700697 int mLoadedCount;
698 int mLastCount;
699 int mUnpluggedCount;
700 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700701
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800702 Counter(TimeBase timeBase, Parcel in) {
703 mTimeBase = timeBase;
Christopher Tate4cee7252010-03-19 14:50:40 -0700704 mPluggedCount = in.readInt();
705 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700706 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700707 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700708 mUnpluggedCount = in.readInt();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800709 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700710 }
711
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800712 Counter(TimeBase timeBase) {
713 mTimeBase = timeBase;
714 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700715 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700716
Dianne Hackborn617f8772009-03-31 15:04:46 -0700717 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700718 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700719 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700720 out.writeInt(mUnpluggedCount);
721 }
722
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800723 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700724 mUnpluggedCount = mPluggedCount;
725 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700726 }
727
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800728 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700729 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700730 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700731
Dianne Hackborn617f8772009-03-31 15:04:46 -0700732 /**
733 * Writes a possibly null Counter to a Parcel.
734 *
735 * @param out the Parcel to be written to.
736 * @param counter a Counter, or null.
737 */
738 public static void writeCounterToParcel(Parcel out, Counter counter) {
739 if (counter == null) {
740 out.writeInt(0); // indicates null
741 return;
742 }
743 out.writeInt(1); // indicates non-null
744
745 counter.writeToParcel(out);
746 }
747
748 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700749 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700750 int val = mCount.get();
751 if (which == STATS_SINCE_UNPLUGGED) {
752 val -= mUnpluggedCount;
753 } else if (which != STATS_SINCE_CHARGED) {
754 val -= mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700755 }
756
757 return val;
758 }
759
760 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700761 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700762 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
763 + " mUnpluggedCount=" + mUnpluggedCount
764 + " mPluggedCount=" + mPluggedCount);
765 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700766
Christopher Tate4cee7252010-03-19 14:50:40 -0700767 void stepAtomic() {
768 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700769 }
770
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700771 /**
772 * Clear state of this counter.
773 */
774 void reset(boolean detachIfReset) {
775 mCount.set(0);
776 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
777 if (detachIfReset) {
778 detach();
779 }
780 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700781
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700782 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800783 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700784 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700785
Dianne Hackborn617f8772009-03-31 15:04:46 -0700786 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700787 int count = mCount.get();
788 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700789 }
790
791 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700792 mLoadedCount = in.readInt();
793 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700794 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700795 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700796 }
797 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700798
799 public static class SamplingCounter extends Counter {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800800 SamplingCounter(TimeBase timeBase, Parcel in) {
801 super(timeBase, in);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700802 }
803
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800804 SamplingCounter(TimeBase timeBase) {
805 super(timeBase);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700806 }
807
Christopher Tate4cee7252010-03-19 14:50:40 -0700808 public void addCountAtomic(long count) {
809 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700810 }
811 }
812
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700813 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800814 final TimeBase mTimeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700815 long mCount;
816 long mLoadedCount;
817 long mLastCount;
818 long mUnpluggedCount;
819 long mPluggedCount;
820
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800821 LongSamplingCounter(TimeBase timeBase, Parcel in) {
822 mTimeBase = timeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700823 mPluggedCount = in.readLong();
824 mCount = mPluggedCount;
825 mLoadedCount = in.readLong();
826 mLastCount = 0;
827 mUnpluggedCount = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800828 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700829 }
830
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800831 LongSamplingCounter(TimeBase timeBase) {
832 mTimeBase = timeBase;
833 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700834 }
835
836 public void writeToParcel(Parcel out) {
837 out.writeLong(mCount);
838 out.writeLong(mLoadedCount);
839 out.writeLong(mUnpluggedCount);
840 }
841
842 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800843 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700844 mUnpluggedCount = mPluggedCount;
845 mCount = mPluggedCount;
846 }
847
848 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800849 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700850 mPluggedCount = mCount;
851 }
852
853 public long getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700854 long val = mCount;
855 if (which == STATS_SINCE_UNPLUGGED) {
856 val -= mUnpluggedCount;
857 } else if (which != STATS_SINCE_CHARGED) {
858 val -= mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700859 }
860
861 return val;
862 }
863
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700864 @Override
865 public void logState(Printer pw, String prefix) {
866 pw.println(prefix + "mCount=" + mCount
867 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
868 + " mUnpluggedCount=" + mUnpluggedCount
869 + " mPluggedCount=" + mPluggedCount);
870 }
871
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700872 void addCountLocked(long count) {
873 mCount += count;
874 }
875
876 /**
877 * Clear state of this counter.
878 */
879 void reset(boolean detachIfReset) {
880 mCount = 0;
881 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
882 if (detachIfReset) {
883 detach();
884 }
885 }
886
887 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800888 mTimeBase.remove(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700889 }
890
891 void writeSummaryFromParcelLocked(Parcel out) {
892 out.writeLong(mCount);
893 }
894
895 void readSummaryFromParcelLocked(Parcel in) {
896 mLoadedCount = in.readLong();
897 mCount = mLoadedCount;
898 mLastCount = 0;
899 mUnpluggedCount = mPluggedCount = mLoadedCount;
900 }
901 }
902
Dianne Hackborn617f8772009-03-31 15:04:46 -0700903 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 * State for keeping track of timing information.
905 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800906 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 final int mType;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800908 final TimeBase mTimeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 int mCount;
911 int mLoadedCount;
912 int mLastCount;
913 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 // Times are in microseconds for better accuracy when dividing by the
916 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 /**
919 * The total time we have accumulated since the start of the original
920 * boot, to the last time something interesting happened in the
921 * current run.
922 */
923 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 /**
926 * The total time we loaded for the previous runs. Subtract this from
927 * mTotalTime to find the time for the current run of the system.
928 */
929 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 /**
932 * The run time of the last run of the system, as loaded from the
933 * saved data.
934 */
935 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 /**
938 * The value of mTotalTime when unplug() was last called. Subtract
939 * this from mTotalTime to find the time since the last unplug from
940 * power.
941 */
942 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700943
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700944 /**
Adam Lesinskie08af192015-03-25 16:42:59 -0700945 * The total time this timer has been running until the latest mark has been set.
946 * Subtract this from mTotalTime to get the time spent running since the mark was set.
947 */
948 long mTimeBeforeMark;
949
950 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700951 * Constructs from a parcel.
952 * @param type
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800953 * @param timeBase
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700954 * @param in
955 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800956 Timer(int type, TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800958 mTimeBase = timeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 mCount = in.readInt();
961 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700962 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 mUnpluggedCount = in.readInt();
964 mTotalTime = in.readLong();
965 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700966 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 mUnpluggedTime = in.readLong();
Adam Lesinskie08af192015-03-25 16:42:59 -0700968 mTimeBeforeMark = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800969 timeBase.add(this);
Dianne Hackborn29325132014-05-21 15:01:03 -0700970 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 }
972
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800973 Timer(int type, TimeBase timeBase) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800975 mTimeBase = timeBase;
976 timeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 }
Evan Millarc64edde2009-04-18 12:26:32 -0700978
979 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700980
Evan Millarc64edde2009-04-18 12:26:32 -0700981 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700982
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700983 /**
984 * Clear state of this timer. Returns true if the timer is inactive
985 * so can be completely dropped.
986 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800987 boolean reset(boolean detachIfReset) {
Adam Lesinskie08af192015-03-25 16:42:59 -0700988 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700989 mCount = mLoadedCount = mLastCount = 0;
990 if (detachIfReset) {
991 detach();
992 }
993 return true;
994 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700995
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700996 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800997 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700998 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700999
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001000 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
Dianne Hackborn29325132014-05-21 15:01:03 -07001001 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
1002 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 out.writeInt(mCount);
1004 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 out.writeInt(mUnpluggedCount);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001006 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 out.writeLong(mUnpluggedTime);
Adam Lesinskie08af192015-03-25 16:42:59 -07001009 out.writeLong(mTimeBeforeMark);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 }
1011
Adam Lesinskie08af192015-03-25 16:42:59 -07001012 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001013 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001015 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 + " old mUnpluggedTime=" + mUnpluggedTime
1017 + " old mUnpluggedCount=" + mUnpluggedCount);
1018 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001019 mUnpluggedTime = computeRunTimeLocked(baseRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 mUnpluggedCount = mCount;
1021 if (DEBUG && mType < 0) {
1022 Log.v(TAG, "unplug #" + mType
1023 + ": new mUnpluggedTime=" + mUnpluggedTime
1024 + " new mUnpluggedCount=" + mUnpluggedCount);
1025 }
1026 }
1027
Adam Lesinskie08af192015-03-25 16:42:59 -07001028 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001029 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001030 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001031 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
Evan Millarc64edde2009-04-18 12:26:32 -07001032 + " old mTotalTime=" + mTotalTime);
1033 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001034 mTotalTime = computeRunTimeLocked(baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001035 mCount = computeCurrentCountLocked();
1036 if (DEBUG && mType < 0) {
1037 Log.v(TAG, "plug #" + mType
1038 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001039 }
1040 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042 /**
1043 * Writes a possibly null Timer to a Parcel.
1044 *
1045 * @param out the Parcel to be written to.
1046 * @param timer a Timer, or null.
1047 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001048 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 if (timer == null) {
1050 out.writeInt(0); // indicates null
1051 return;
1052 }
1053 out.writeInt(1); // indicates non-null
1054
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001055 timer.writeToParcel(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001056 }
1057
1058 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001059 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001060 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1061 if (which == STATS_SINCE_UNPLUGGED) {
1062 val -= mUnpluggedTime;
1063 } else if (which != STATS_SINCE_CHARGED) {
1064 val -= mLoadedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 }
1066
1067 return val;
1068 }
1069
1070 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001071 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001072 int val = computeCurrentCountLocked();
1073 if (which == STATS_SINCE_UNPLUGGED) {
1074 val -= mUnpluggedCount;
1075 } else if (which != STATS_SINCE_CHARGED) {
1076 val -= mLoadedCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 }
1078
1079 return val;
1080 }
1081
Adam Lesinskie08af192015-03-25 16:42:59 -07001082 @Override
1083 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) {
1084 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1085 return val - mTimeBeforeMark;
1086 }
1087
1088 @Override
Dianne Hackborn627bba72009-03-24 22:32:56 -07001089 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001090 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001091 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
1092 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001093 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001095 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001097 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001098
1099
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001100 void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
1101 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1102 out.writeLong(runTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001103 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -07001104 }
1105
1106 void readSummaryFromParcelLocked(Parcel in) {
1107 // Multiply by 1000 for backwards compatibility
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001108 mTotalTime = mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001109 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001110 mUnpluggedTime = mTotalTime;
1111 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001112 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001113 mUnpluggedCount = mCount;
Adam Lesinskie08af192015-03-25 16:42:59 -07001114
1115 // When reading the summary, we set the mark to be the latest information.
1116 mTimeBeforeMark = mTotalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001117 }
1118 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001119
Evan Millarc64edde2009-04-18 12:26:32 -07001120 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001121
Evan Millarc64edde2009-04-18 12:26:32 -07001122 /**
1123 * The most recent reported count from /proc/wakelocks.
1124 */
1125 int mCurrentReportedCount;
1126
1127 /**
1128 * The reported count from /proc/wakelocks when unplug() was last
1129 * called.
1130 */
1131 int mUnpluggedReportedCount;
1132
1133 /**
1134 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001135 */
Evan Millarc64edde2009-04-18 12:26:32 -07001136 long mCurrentReportedTotalTime;
1137
1138
1139 /**
1140 * The reported total_time from /proc/wakelocks when unplug() was last
1141 * called.
1142 */
1143 long mUnpluggedReportedTotalTime;
1144
1145 /**
1146 * Whether we are currently in a discharge cycle.
1147 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001148 boolean mTimeBaseRunning;
Evan Millarc64edde2009-04-18 12:26:32 -07001149
1150 /**
1151 * Whether we are currently recording reported values.
1152 */
1153 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001154
Evan Millarc64edde2009-04-18 12:26:32 -07001155 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001156 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -07001157 */
1158 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001159
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001160 SamplingTimer(TimeBase timeBase, Parcel in) {
1161 super(0, timeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07001162 mCurrentReportedCount = in.readInt();
1163 mUnpluggedReportedCount = in.readInt();
1164 mCurrentReportedTotalTime = in.readLong();
1165 mUnpluggedReportedTotalTime = in.readLong();
1166 mTrackingReportedValues = in.readInt() == 1;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001167 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001168 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001169
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001170 SamplingTimer(TimeBase timeBase, boolean trackReportedValues) {
1171 super(0, timeBase);
Evan Millarc64edde2009-04-18 12:26:32 -07001172 mTrackingReportedValues = trackReportedValues;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001173 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001174 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001175
Evan Millarc64edde2009-04-18 12:26:32 -07001176 public void setStale() {
1177 mTrackingReportedValues = false;
1178 mUnpluggedReportedTotalTime = 0;
1179 mUnpluggedReportedCount = 0;
1180 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001181
Evan Millarc64edde2009-04-18 12:26:32 -07001182 public void setUpdateVersion(int version) {
1183 mUpdateVersion = version;
1184 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001185
Evan Millarc64edde2009-04-18 12:26:32 -07001186 public int getUpdateVersion() {
1187 return mUpdateVersion;
1188 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001189
Evan Millarc64edde2009-04-18 12:26:32 -07001190 public void updateCurrentReportedCount(int count) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001191 if (mTimeBaseRunning && mUnpluggedReportedCount == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001192 // Updating the reported value for the first time.
1193 mUnpluggedReportedCount = count;
1194 // If we are receiving an update update mTrackingReportedValues;
1195 mTrackingReportedValues = true;
1196 }
1197 mCurrentReportedCount = count;
1198 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001199
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001200 public void addCurrentReportedCount(int delta) {
1201 updateCurrentReportedCount(mCurrentReportedCount + delta);
1202 }
1203
Evan Millarc64edde2009-04-18 12:26:32 -07001204 public void updateCurrentReportedTotalTime(long totalTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001205 if (mTimeBaseRunning && mUnpluggedReportedTotalTime == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001206 // Updating the reported value for the first time.
1207 mUnpluggedReportedTotalTime = totalTime;
1208 // If we are receiving an update update mTrackingReportedValues;
1209 mTrackingReportedValues = true;
1210 }
1211 mCurrentReportedTotalTime = totalTime;
1212 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001213
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001214 public void addCurrentReportedTotalTime(long delta) {
1215 updateCurrentReportedTotalTime(mCurrentReportedTotalTime + delta);
1216 }
1217
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001218 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1219 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001220 if (mTrackingReportedValues) {
1221 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
1222 mUnpluggedReportedCount = mCurrentReportedCount;
1223 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001224 mTimeBaseRunning = true;
Evan Millarc64edde2009-04-18 12:26:32 -07001225 }
1226
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001227 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1228 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1229 mTimeBaseRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001230 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001231
Evan Millarc64edde2009-04-18 12:26:32 -07001232 public void logState(Printer pw, String prefix) {
1233 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001234 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -07001235 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
1236 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
1237 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
1238 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001239
Evan Millarc64edde2009-04-18 12:26:32 -07001240 protected long computeRunTimeLocked(long curBatteryRealtime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001241 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001242 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
1243 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001244
Evan Millarc64edde2009-04-18 12:26:32 -07001245 protected int computeCurrentCountLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001246 return mCount + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001247 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
1248 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001249
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001250 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1251 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001252 out.writeInt(mCurrentReportedCount);
1253 out.writeInt(mUnpluggedReportedCount);
1254 out.writeLong(mCurrentReportedTotalTime);
1255 out.writeLong(mUnpluggedReportedTotalTime);
1256 out.writeInt(mTrackingReportedValues ? 1 : 0);
1257 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001258
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001259 boolean reset(boolean detachIfReset) {
1260 super.reset(detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001261 setStale();
1262 return true;
1263 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001264
Evan Millarc64edde2009-04-18 12:26:32 -07001265 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
1266 super.writeSummaryFromParcelLocked(out, batteryRealtime);
1267 out.writeLong(mCurrentReportedTotalTime);
1268 out.writeInt(mCurrentReportedCount);
1269 out.writeInt(mTrackingReportedValues ? 1 : 0);
1270 }
1271
1272 void readSummaryFromParcelLocked(Parcel in) {
1273 super.readSummaryFromParcelLocked(in);
1274 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
1275 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
1276 mTrackingReportedValues = in.readInt() == 1;
1277 }
1278 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001279
Evan Millarc64edde2009-04-18 12:26:32 -07001280 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001281 * A timer that increments in batches. It does not run for durations, but just jumps
1282 * for a pre-determined amount.
1283 */
1284 public static final class BatchTimer extends Timer {
1285 final Uid mUid;
1286
1287 /**
1288 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
1289 */
1290 long mLastAddedTime;
1291
1292 /**
1293 * The last duration that we added to the timer. This is in microseconds.
1294 */
1295 long mLastAddedDuration;
1296
1297 /**
1298 * Whether we are currently in a discharge cycle.
1299 */
1300 boolean mInDischarge;
1301
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001302 BatchTimer(Uid uid, int type, TimeBase timeBase, Parcel in) {
1303 super(type, timeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001304 mUid = uid;
1305 mLastAddedTime = in.readLong();
1306 mLastAddedDuration = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001307 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001308 }
1309
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001310 BatchTimer(Uid uid, int type, TimeBase timeBase) {
1311 super(type, timeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001312 mUid = uid;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001313 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001314 }
1315
1316 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001317 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1318 super.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001319 out.writeLong(mLastAddedTime);
1320 out.writeLong(mLastAddedDuration);
1321 }
1322
1323 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001324 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001325 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
1326 mInDischarge = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001327 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001328 }
1329
1330 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001331 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001332 recomputeLastDuration(elapsedRealtime, false);
1333 mInDischarge = true;
1334 // If we are still within the last added duration, then re-added whatever remains.
1335 if (mLastAddedTime == elapsedRealtime) {
1336 mTotalTime += mLastAddedDuration;
1337 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001338 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001339 }
1340
1341 @Override
1342 public void logState(Printer pw, String prefix) {
1343 super.logState(pw, prefix);
1344 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
1345 + " mLastAddedDuration=" + mLastAddedDuration);
1346 }
1347
1348 private long computeOverage(long curTime) {
1349 if (mLastAddedTime > 0) {
1350 return mLastTime + mLastAddedDuration - curTime;
1351 }
1352 return 0;
1353 }
1354
1355 private void recomputeLastDuration(long curTime, boolean abort) {
1356 final long overage = computeOverage(curTime);
1357 if (overage > 0) {
1358 // Aborting before the duration ran out -- roll back the remaining
1359 // duration. Only do this if currently discharging; otherwise we didn't
1360 // actually add the time.
1361 if (mInDischarge) {
1362 mTotalTime -= overage;
1363 }
1364 if (abort) {
1365 mLastAddedTime = 0;
1366 } else {
1367 mLastAddedTime = curTime;
1368 mLastAddedDuration -= overage;
1369 }
1370 }
1371 }
1372
1373 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
1374 final long now = SystemClock.elapsedRealtime() * 1000;
1375 recomputeLastDuration(now, true);
1376 mLastAddedTime = now;
1377 mLastAddedDuration = durationMillis * 1000;
1378 if (mInDischarge) {
1379 mTotalTime += mLastAddedDuration;
1380 mCount++;
1381 }
1382 }
1383
1384 public void abortLastDuration(BatteryStatsImpl stats) {
1385 final long now = SystemClock.elapsedRealtime() * 1000;
1386 recomputeLastDuration(now, true);
1387 }
1388
1389 @Override
1390 protected int computeCurrentCountLocked() {
1391 return mCount;
1392 }
1393
1394 @Override
1395 protected long computeRunTimeLocked(long curBatteryRealtime) {
1396 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000);
1397 if (overage > 0) {
1398 return mTotalTime = overage;
1399 }
1400 return mTotalTime;
1401 }
1402
1403 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001404 boolean reset(boolean detachIfReset) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001405 final long now = SystemClock.elapsedRealtime() * 1000;
1406 recomputeLastDuration(now, true);
1407 boolean stillActive = mLastAddedTime == now;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001408 super.reset(!stillActive && detachIfReset);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001409 return !stillActive;
1410 }
1411 }
1412
1413 /**
Evan Millarc64edde2009-04-18 12:26:32 -07001414 * State for keeping track of timing information.
1415 */
1416 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001417 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07001418 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001419
Evan Millarc64edde2009-04-18 12:26:32 -07001420 int mNesting;
1421
Evan Millarc64edde2009-04-18 12:26:32 -07001422 /**
1423 * The last time at which we updated the timer. If mNesting is > 0,
1424 * subtract this from the current battery time to find the amount of
1425 * time we have been running since we last computed an update.
1426 */
1427 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001428
Evan Millarc64edde2009-04-18 12:26:32 -07001429 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001430 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -07001431 * was actually held for an interesting duration.
1432 */
1433 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001434
Amith Yamasanif37447b2009-10-08 18:28:01 -07001435 long mTimeout;
1436
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001437 /**
1438 * For partial wake locks, keep track of whether we are in the list
1439 * to consume CPU cycles.
1440 */
1441 boolean mInList;
1442
1443 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001444 TimeBase timeBase, Parcel in) {
1445 super(type, timeBase, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001446 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001447 mTimerPool = timerPool;
1448 mUpdateTime = in.readLong();
1449 }
1450
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001451 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001452 TimeBase timeBase) {
1453 super(type, timeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001454 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001455 mTimerPool = timerPool;
1456 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001457
Amith Yamasanif37447b2009-10-08 18:28:01 -07001458 void setTimeout(long timeout) {
1459 mTimeout = timeout;
1460 }
1461
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001462 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1463 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001464 out.writeLong(mUpdateTime);
1465 }
1466
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001467 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001468 if (mNesting > 0) {
1469 if (DEBUG && mType < 0) {
1470 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
1471 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001472 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1473 mUpdateTime = baseRealtime;
Evan Millarc64edde2009-04-18 12:26:32 -07001474 if (DEBUG && mType < 0) {
1475 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
1476 }
1477 }
1478 }
1479
1480 public void logState(Printer pw, String prefix) {
1481 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001482 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 + " mAcquireTime=" + mAcquireTime);
1484 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001485
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001486 void startRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 if (mNesting++ == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001488 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001489 mUpdateTime = batteryRealtime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 if (mTimerPool != null) {
1491 // Accumulate time to all currently active timers before adding
1492 // this new one to the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001493 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 // Add this timer to the active pool
1495 mTimerPool.add(this);
1496 }
1497 // Increment the count
1498 mCount++;
1499 mAcquireTime = mTotalTime;
1500 if (DEBUG && mType < 0) {
1501 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
1502 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1503 + " mAcquireTime=" + mAcquireTime);
1504 }
1505 }
1506 }
1507
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001508 boolean isRunningLocked() {
1509 return mNesting > 0;
1510 }
1511
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001512 void stopRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 // Ignore attempt to stop a timer that isn't running
1514 if (mNesting == 0) {
1515 return;
1516 }
1517 if (--mNesting == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001518 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 if (mTimerPool != null) {
1520 // Accumulate time to all active counters, scaled by the total
1521 // active in the pool, before taking this one out of the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001522 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 // Remove this timer from the active pool
1524 mTimerPool.remove(this);
1525 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 mNesting = 1;
1527 mTotalTime = computeRunTimeLocked(batteryRealtime);
1528 mNesting = 0;
1529 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 if (DEBUG && mType < 0) {
1532 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
1533 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1534 + " mAcquireTime=" + mAcquireTime);
1535 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 if (mTotalTime == mAcquireTime) {
1538 // If there was no change in the time, then discard this
1539 // count. A somewhat cheezy strategy, but hey.
1540 mCount--;
1541 }
1542 }
1543 }
1544
Dianne Hackborn10eaa852014-07-22 22:54:55 -07001545 void stopAllRunningLocked(long elapsedRealtimeMs) {
1546 if (mNesting > 0) {
1547 mNesting = 1;
1548 stopRunningLocked(elapsedRealtimeMs);
1549 }
1550 }
1551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 // Update the total time for all other running Timers with the same type as this Timer
1553 // due to a change in timer count
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001554 private static long refreshTimersLocked(long batteryRealtime,
1555 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001556 long selfTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 final int N = pool.size();
1558 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07001559 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 long heldTime = batteryRealtime - t.mUpdateTime;
1561 if (heldTime > 0) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001562 final long myTime = heldTime / N;
1563 if (t == self) {
1564 selfTime = myTime;
1565 }
1566 t.mTotalTime += myTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 }
1568 t.mUpdateTime = batteryRealtime;
1569 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001570 return selfTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 }
1572
Evan Millarc64edde2009-04-18 12:26:32 -07001573 @Override
1574 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001575 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
1576 curBatteryRealtime = mUpdateTime + mTimeout;
1577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001578 return mTotalTime + (mNesting > 0
1579 ? (curBatteryRealtime - mUpdateTime)
1580 / (mTimerPool != null ? mTimerPool.size() : 1)
1581 : 0);
1582 }
1583
Evan Millarc64edde2009-04-18 12:26:32 -07001584 @Override
1585 protected int computeCurrentCountLocked() {
1586 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 }
1588
Adam Lesinskie08af192015-03-25 16:42:59 -07001589 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001590 boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001591 boolean canDetach = mNesting <= 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001592 super.reset(canDetach && detachIfReset);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001593 if (mNesting > 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001594 mUpdateTime = mTimeBase.getRealtime(SystemClock.elapsedRealtime() * 1000);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001595 }
1596 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001597 return canDetach;
1598 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001599
Adam Lesinskie08af192015-03-25 16:42:59 -07001600 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001601 void detach() {
1602 super.detach();
1603 if (mTimerPool != null) {
1604 mTimerPool.remove(this);
1605 }
1606 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001607
Adam Lesinskie08af192015-03-25 16:42:59 -07001608 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001610 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 mNesting = 0;
1612 }
Adam Lesinskie08af192015-03-25 16:42:59 -07001613
1614 /**
1615 * Set the mark so that we can query later for the total time the timer has
1616 * accumulated since this point. The timer can be running or not.
1617 *
1618 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds.
1619 */
1620 public void setMark(long elapsedRealtimeMs) {
1621 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
1622 if (mNesting > 0) {
1623 // We are running.
1624 if (mTimerPool != null) {
1625 refreshTimersLocked(batteryRealtime, mTimerPool, this);
1626 } else {
1627 mTotalTime += batteryRealtime - mUpdateTime;
1628 mUpdateTime = batteryRealtime;
1629 }
1630 }
1631 mTimeBeforeMark = mTotalTime;
1632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001634
Dianne Hackbornd953c532014-08-16 18:17:38 -07001635 public abstract class OverflowArrayMap<T> {
1636 private static final String OVERFLOW_NAME = "*overflow*";
1637
1638 final ArrayMap<String, T> mMap = new ArrayMap<>();
1639 T mCurOverflow;
1640 ArrayMap<String, MutableInt> mActiveOverflow;
1641
1642 public OverflowArrayMap() {
1643 }
1644
1645 public ArrayMap<String, T> getMap() {
1646 return mMap;
1647 }
1648
1649 public void clear() {
1650 mMap.clear();
1651 mCurOverflow = null;
1652 mActiveOverflow = null;
1653 }
1654
1655 public void add(String name, T obj) {
1656 mMap.put(name, obj);
1657 if (OVERFLOW_NAME.equals(name)) {
1658 mCurOverflow = obj;
1659 }
1660 }
1661
1662 public void cleanup() {
1663 if (mActiveOverflow != null) {
1664 if (mActiveOverflow.size() == 0) {
1665 mActiveOverflow = null;
1666 }
1667 }
1668 if (mActiveOverflow == null) {
1669 // There is no currently active overflow, so we should no longer have
1670 // an overflow entry.
1671 if (mMap.containsKey(OVERFLOW_NAME)) {
1672 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry "
1673 + mMap.get(OVERFLOW_NAME));
1674 mMap.remove(OVERFLOW_NAME);
1675 }
1676 mCurOverflow = null;
1677 } else {
1678 // There is currently active overflow, so we should still have an overflow entry.
1679 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) {
1680 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur="
1681 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME));
1682 }
1683 }
1684 }
1685
1686 public T startObject(String name) {
1687 T obj = mMap.get(name);
1688 if (obj != null) {
1689 return obj;
1690 }
1691
1692 // No object exists for the given name, but do we currently have it
1693 // running as part of the overflow?
1694 if (mActiveOverflow != null) {
1695 MutableInt over = mActiveOverflow.get(name);
1696 if (over != null) {
1697 // We are already actively counting this name in the overflow object.
1698 obj = mCurOverflow;
1699 if (obj == null) {
1700 // Shouldn't be here, but we'll try to recover.
1701 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow");
1702 obj = mCurOverflow = instantiateObject();
1703 mMap.put(OVERFLOW_NAME, obj);
1704 }
1705 over.value++;
1706 return obj;
1707 }
1708 }
1709
1710 // No object exists for given name nor in the overflow; we need to make
1711 // a new one.
1712 final int N = mMap.size();
1713 if (N >= MAX_WAKELOCKS_PER_UID) {
1714 // Went over the limit on number of objects to track; this one goes
1715 // in to the overflow.
1716 obj = mCurOverflow;
1717 if (obj == null) {
1718 // Need to start overflow now...
1719 obj = mCurOverflow = instantiateObject();
1720 mMap.put(OVERFLOW_NAME, obj);
1721 }
1722 if (mActiveOverflow == null) {
1723 mActiveOverflow = new ArrayMap<>();
1724 }
1725 mActiveOverflow.put(name, new MutableInt(1));
1726 return obj;
1727 }
1728
1729 // Normal case where we just need to make a new object.
1730 obj = instantiateObject();
1731 mMap.put(name, obj);
1732 return obj;
1733 }
1734
1735 public T stopObject(String name) {
1736 T obj = mMap.get(name);
1737 if (obj != null) {
1738 return obj;
1739 }
1740
1741 // No object exists for the given name, but do we currently have it
1742 // running as part of the overflow?
1743 if (mActiveOverflow != null) {
1744 MutableInt over = mActiveOverflow.get(name);
1745 if (over != null) {
1746 // We are already actively counting this name in the overflow object.
1747 obj = mCurOverflow;
1748 if (obj != null) {
1749 over.value--;
1750 if (over.value <= 0) {
1751 mActiveOverflow.remove(name);
1752 }
1753 return obj;
1754 }
1755 }
1756 }
1757
1758 // Huh, they are stopping an active operation but we can't find one!
1759 // That's not good.
1760 Slog.wtf(TAG, "Unable to find object for " + name + " mapsize="
1761 + mMap.size() + " activeoverflow=" + mActiveOverflow
1762 + " curoverflow=" + mCurOverflow);
1763 return null;
1764 }
1765
1766 public abstract T instantiateObject();
1767 }
1768
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001769 /*
1770 * Get the wakeup reason counter, and create a new one if one
1771 * doesn't already exist.
1772 */
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001773 public SamplingTimer getWakeupReasonTimerLocked(String name) {
1774 SamplingTimer timer = mWakeupReasonStats.get(name);
1775 if (timer == null) {
1776 timer = new SamplingTimer(mOnBatteryTimeBase, true);
1777 mWakeupReasonStats.put(name, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001778 }
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001779 return timer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001780 }
1781
Evan Millarc64edde2009-04-18 12:26:32 -07001782 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001783 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001784 * doesn't already exist.
1785 */
1786 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1787 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1788 if (kwlt == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001789 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, true /* track reported values */);
Evan Millarc64edde2009-04-18 12:26:32 -07001790 mKernelWakelockStats.put(name, kwlt);
1791 }
1792 return kwlt;
1793 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001794
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001795 private int writeHistoryTag(HistoryTag tag) {
1796 Integer idxObj = mHistoryTagPool.get(tag);
1797 int idx;
1798 if (idxObj != null) {
1799 idx = idxObj;
1800 } else {
1801 idx = mNextHistoryTagIdx;
1802 HistoryTag key = new HistoryTag();
1803 key.setTo(tag);
1804 tag.poolIdx = idx;
1805 mHistoryTagPool.put(key, idx);
1806 mNextHistoryTagIdx++;
1807 mNumHistoryTagChars += key.string.length() + 1;
1808 }
1809 return idx;
1810 }
1811
1812 private void readHistoryTag(int index, HistoryTag tag) {
1813 tag.string = mReadHistoryStrings[index];
1814 tag.uid = mReadHistoryUids[index];
1815 tag.poolIdx = index;
1816 }
1817
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001818 // Part of initial delta int that specifies the time delta.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001819 static final int DELTA_TIME_MASK = 0x7ffff;
1820 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
1821 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
1822 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001823 // Flag in delta int: a new battery level int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001824 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001825 // Flag in delta int: a new full state and battery status int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001826 static final int DELTA_STATE_FLAG = 0x00100000;
1827 // Flag in delta int: a new full state2 int follows.
1828 static final int DELTA_STATE2_FLAG = 0x00200000;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001829 // Flag in delta int: contains a wakelock or wakeReason tag.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001830 static final int DELTA_WAKELOCK_FLAG = 0x00400000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001831 // Flag in delta int: contains an event description.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001832 static final int DELTA_EVENT_FLAG = 0x00800000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001833 // These upper bits are the frequently changing state bits.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001834 static final int DELTA_STATE_MASK = 0xff000000;
1835
1836 // These are the pieces of battery state that are packed in to the upper bits of
1837 // the state int that have been packed in to the first delta int. They must fit
1838 // in DELTA_STATE_MASK.
1839 static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
1840 static final int STATE_BATTERY_STATUS_SHIFT = 29;
1841 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
1842 static final int STATE_BATTERY_HEALTH_SHIFT = 26;
1843 static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
1844 static final int STATE_BATTERY_PLUG_SHIFT = 24;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001845
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001846 // We use the low bit of the battery state int to indicate that we have full details
1847 // from a battery level change.
1848 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001;
1849
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001850 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001851 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001852 dest.writeInt(DELTA_TIME_ABS);
1853 cur.writeToParcel(dest, 0);
1854 return;
1855 }
1856
1857 final long deltaTime = cur.time - last.time;
1858 final int lastBatteryLevelInt = buildBatteryLevelInt(last);
1859 final int lastStateInt = buildStateInt(last);
1860
1861 int deltaTimeToken;
1862 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
1863 deltaTimeToken = DELTA_TIME_LONG;
1864 } else if (deltaTime >= DELTA_TIME_ABS) {
1865 deltaTimeToken = DELTA_TIME_INT;
1866 } else {
1867 deltaTimeToken = (int)deltaTime;
1868 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001869 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001870 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel
1871 ? BATTERY_DELTA_LEVEL_FLAG : 0;
1872 final boolean computeStepDetails = includeStepDetails != 0
1873 || mLastHistoryStepDetails == null;
1874 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001875 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
1876 if (batteryLevelIntChanged) {
1877 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
1878 }
1879 final int stateInt = buildStateInt(cur);
1880 final boolean stateIntChanged = stateInt != lastStateInt;
1881 if (stateIntChanged) {
1882 firstToken |= DELTA_STATE_FLAG;
1883 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001884 final boolean state2IntChanged = cur.states2 != last.states2;
1885 if (state2IntChanged) {
1886 firstToken |= DELTA_STATE2_FLAG;
1887 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001888 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001889 firstToken |= DELTA_WAKELOCK_FLAG;
1890 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001891 if (cur.eventCode != HistoryItem.EVENT_NONE) {
1892 firstToken |= DELTA_EVENT_FLAG;
1893 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001894 dest.writeInt(firstToken);
1895 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
1896 + " deltaTime=" + deltaTime);
1897
1898 if (deltaTimeToken >= DELTA_TIME_INT) {
1899 if (deltaTimeToken == DELTA_TIME_INT) {
1900 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
1901 dest.writeInt((int)deltaTime);
1902 } else {
1903 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
1904 dest.writeLong(deltaTime);
1905 }
1906 }
1907 if (batteryLevelIntChanged) {
1908 dest.writeInt(batteryLevelInt);
1909 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
1910 + Integer.toHexString(batteryLevelInt)
1911 + " batteryLevel=" + cur.batteryLevel
1912 + " batteryTemp=" + cur.batteryTemperature
1913 + " batteryVolt=" + (int)cur.batteryVoltage);
1914 }
1915 if (stateIntChanged) {
1916 dest.writeInt(stateInt);
1917 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
1918 + Integer.toHexString(stateInt)
1919 + " batteryStatus=" + cur.batteryStatus
1920 + " batteryHealth=" + cur.batteryHealth
1921 + " batteryPlugType=" + cur.batteryPlugType
1922 + " states=0x" + Integer.toHexString(cur.states));
1923 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001924 if (state2IntChanged) {
1925 dest.writeInt(cur.states2);
1926 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
1927 + Integer.toHexString(cur.states2));
1928 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001929 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
1930 int wakeLockIndex;
1931 int wakeReasonIndex;
1932 if (cur.wakelockTag != null) {
1933 wakeLockIndex = writeHistoryTag(cur.wakelockTag);
1934 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
1935 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
1936 } else {
1937 wakeLockIndex = 0xffff;
1938 }
1939 if (cur.wakeReasonTag != null) {
1940 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
1941 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
1942 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
1943 } else {
1944 wakeReasonIndex = 0xffff;
1945 }
1946 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001947 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001948 if (cur.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001949 int index = writeHistoryTag(cur.eventTag);
1950 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
Dianne Hackborn099bc622014-01-22 13:39:16 -08001951 dest.writeInt(codeAndIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001952 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
1953 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
1954 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001955 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001956 if (computeStepDetails) {
1957 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
1958 if (includeStepDetails != 0) {
1959 mCurHistoryStepDetails.writeToParcel(dest);
1960 }
1961 cur.stepDetails = mCurHistoryStepDetails;
1962 mLastHistoryStepDetails = mCurHistoryStepDetails;
1963 } else {
1964 cur.stepDetails = null;
1965 }
1966 if (mLastHistoryStepLevel < cur.batteryLevel) {
1967 mLastHistoryStepDetails = null;
1968 }
1969 mLastHistoryStepLevel = cur.batteryLevel;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001970 }
1971
1972 private int buildBatteryLevelInt(HistoryItem h) {
1973 return ((((int)h.batteryLevel)<<25)&0xfe000000)
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001974 | ((((int)h.batteryTemperature)<<14)&0x01ff8000)
1975 | ((((int)h.batteryVoltage)<<1)&0x00007fff);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001976 }
1977
1978 private int buildStateInt(HistoryItem h) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001979 int plugType = 0;
1980 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
1981 plugType = 1;
1982 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
1983 plugType = 2;
1984 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
1985 plugType = 3;
1986 }
1987 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
1988 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
1989 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001990 | (h.states&(~DELTA_STATE_MASK));
1991 }
1992
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001993 private void computeHistoryStepDetails(final HistoryStepDetails out,
1994 final HistoryStepDetails last) {
1995 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out;
1996
1997 // Perform a CPU update right after we do this collection, so we have started
1998 // collecting good data for the next step.
1999 requestImmediateCpuUpdate();
2000
2001 if (last == null) {
2002 // We are not generating a delta, so all we need to do is reset the stats
2003 // we will later be doing a delta from.
2004 final int NU = mUidStats.size();
2005 for (int i=0; i<NU; i++) {
2006 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
2007 uid.mLastStepUserTime = uid.mCurStepUserTime;
2008 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
2009 }
2010 mLastStepCpuUserTime = mCurStepCpuUserTime;
2011 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
2012 mLastStepStatUserTime = mCurStepStatUserTime;
2013 mLastStepStatSystemTime = mCurStepStatSystemTime;
2014 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
2015 mLastStepStatIrqTime = mCurStepStatIrqTime;
2016 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
2017 mLastStepStatIdleTime = mCurStepStatIdleTime;
2018 tmp.clear();
2019 return;
2020 }
2021 if (DEBUG) {
2022 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys="
2023 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime
2024 + " irq=" + mLastStepStatIrqTime + " sirq="
2025 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime);
2026 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys="
2027 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime
2028 + " irq=" + mCurStepStatIrqTime + " sirq="
2029 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime);
2030 }
2031 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime);
2032 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime);
2033 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime);
2034 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime);
2035 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime);
2036 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime);
2037 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime);
2038 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime);
2039 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1;
2040 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0;
2041 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0;
2042 final int NU = mUidStats.size();
2043 for (int i=0; i<NU; i++) {
2044 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
2045 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime);
2046 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime);
2047 final int totalTime = totalUTime + totalSTime;
2048 uid.mLastStepUserTime = uid.mCurStepUserTime;
2049 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
2050 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) {
2051 continue;
2052 }
2053 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) {
2054 out.appCpuUid3 = uid.mUid;
2055 out.appCpuUTime3 = totalUTime;
2056 out.appCpuSTime3 = totalSTime;
2057 } else {
2058 out.appCpuUid3 = out.appCpuUid2;
2059 out.appCpuUTime3 = out.appCpuUTime2;
2060 out.appCpuSTime3 = out.appCpuSTime2;
2061 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) {
2062 out.appCpuUid2 = uid.mUid;
2063 out.appCpuUTime2 = totalUTime;
2064 out.appCpuSTime2 = totalSTime;
2065 } else {
2066 out.appCpuUid2 = out.appCpuUid1;
2067 out.appCpuUTime2 = out.appCpuUTime1;
2068 out.appCpuSTime2 = out.appCpuSTime1;
2069 out.appCpuUid1 = uid.mUid;
2070 out.appCpuUTime1 = totalUTime;
2071 out.appCpuSTime1 = totalSTime;
2072 }
2073 }
2074 }
2075 mLastStepCpuUserTime = mCurStepCpuUserTime;
2076 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
2077 mLastStepStatUserTime = mCurStepStatUserTime;
2078 mLastStepStatSystemTime = mCurStepStatSystemTime;
2079 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
2080 mLastStepStatIrqTime = mCurStepStatIrqTime;
2081 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
2082 mLastStepStatIdleTime = mCurStepStatIdleTime;
2083 }
2084
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002085 public void readHistoryDelta(Parcel src, HistoryItem cur) {
2086 int firstToken = src.readInt();
2087 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002088 cur.cmd = HistoryItem.CMD_UPDATE;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002089 cur.numReadInts = 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002090 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
2091 + " deltaTimeToken=" + deltaTimeToken);
2092
2093 if (deltaTimeToken < DELTA_TIME_ABS) {
2094 cur.time += deltaTimeToken;
2095 } else if (deltaTimeToken == DELTA_TIME_ABS) {
2096 cur.time = src.readLong();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002097 cur.numReadInts += 2;
2098 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002099 cur.readFromParcel(src);
2100 return;
2101 } else if (deltaTimeToken == DELTA_TIME_INT) {
2102 int delta = src.readInt();
2103 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002104 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002105 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
2106 } else {
2107 long delta = src.readLong();
2108 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
2109 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002110 cur.numReadInts += 2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002111 }
2112
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002113 final int batteryLevelInt;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002114 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002115 batteryLevelInt = src.readInt();
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002116 cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
2117 cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21);
2118 cur.batteryVoltage = (char)(batteryLevelInt&0x3fff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002119 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002120 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
2121 + Integer.toHexString(batteryLevelInt)
2122 + " batteryLevel=" + cur.batteryLevel
2123 + " batteryTemp=" + cur.batteryTemperature
2124 + " batteryVolt=" + (int)cur.batteryVoltage);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002125 } else {
2126 batteryLevelInt = 0;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002127 }
2128
2129 if ((firstToken&DELTA_STATE_FLAG) != 0) {
2130 int stateInt = src.readInt();
2131 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002132 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
2133 & STATE_BATTERY_STATUS_MASK);
2134 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
2135 & STATE_BATTERY_HEALTH_MASK);
2136 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
2137 & STATE_BATTERY_PLUG_MASK);
2138 switch (cur.batteryPlugType) {
2139 case 1:
2140 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
2141 break;
2142 case 2:
2143 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
2144 break;
2145 case 3:
2146 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
2147 break;
2148 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002149 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002150 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
2151 + Integer.toHexString(stateInt)
2152 + " batteryStatus=" + cur.batteryStatus
2153 + " batteryHealth=" + cur.batteryHealth
2154 + " batteryPlugType=" + cur.batteryPlugType
2155 + " states=0x" + Integer.toHexString(cur.states));
2156 } else {
2157 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK));
2158 }
2159
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002160 if ((firstToken&DELTA_STATE2_FLAG) != 0) {
2161 cur.states2 = src.readInt();
2162 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
2163 + Integer.toHexString(cur.states2));
2164 }
2165
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002166 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002167 int indexes = src.readInt();
2168 int wakeLockIndex = indexes&0xffff;
2169 int wakeReasonIndex = (indexes>>16)&0xffff;
2170 if (wakeLockIndex != 0xffff) {
2171 cur.wakelockTag = cur.localWakelockTag;
2172 readHistoryTag(wakeLockIndex, cur.wakelockTag);
2173 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
2174 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
2175 } else {
2176 cur.wakelockTag = null;
2177 }
2178 if (wakeReasonIndex != 0xffff) {
2179 cur.wakeReasonTag = cur.localWakeReasonTag;
2180 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
2181 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
2182 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
2183 } else {
2184 cur.wakeReasonTag = null;
2185 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002186 cur.numReadInts += 1;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002187 } else {
2188 cur.wakelockTag = null;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002189 cur.wakeReasonTag = null;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002190 }
2191
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002192 if ((firstToken&DELTA_EVENT_FLAG) != 0) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002193 cur.eventTag = cur.localEventTag;
2194 final int codeAndIndex = src.readInt();
Dianne Hackborn099bc622014-01-22 13:39:16 -08002195 cur.eventCode = (codeAndIndex&0xffff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002196 final int index = ((codeAndIndex>>16)&0xffff);
2197 readHistoryTag(index, cur.eventTag);
2198 cur.numReadInts += 1;
2199 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
2200 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
2201 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002202 } else {
2203 cur.eventCode = HistoryItem.EVENT_NONE;
2204 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002205
2206 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) {
2207 cur.stepDetails = mReadHistoryStepDetails;
2208 cur.stepDetails.readFromParcel(src);
2209 } else {
2210 cur.stepDetails = null;
2211 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002212 }
2213
Dianne Hackbornfc064132014-06-02 12:42:12 -07002214 @Override
2215 public void commitCurrentHistoryBatchLocked() {
2216 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
2217 }
2218
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002219 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002220 if (!mHaveBatteryLevel || !mRecordingHistory) {
2221 return;
2222 }
2223
Dianne Hackborn40c87252014-03-19 16:55:40 -07002224 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002225 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates);
2226 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002227 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002228 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002229 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
2230 + Integer.toHexString(diffStates) + " lastDiff="
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002231 + Integer.toHexString(lastDiffStates) + " diff2="
2232 + Integer.toHexString(diffStates2) + " lastDiff2="
2233 + Integer.toHexString(lastDiffStates2));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002234 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002235 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002236 && (diffStates2&lastDiffStates2) == 0
2237 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
2238 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002239 && mHistoryLastWritten.stepDetails == null
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002240 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002241 || cur.eventCode == HistoryItem.EVENT_NONE)
2242 && mHistoryLastWritten.batteryLevel == cur.batteryLevel
2243 && mHistoryLastWritten.batteryStatus == cur.batteryStatus
2244 && mHistoryLastWritten.batteryHealth == cur.batteryHealth
2245 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
2246 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
2247 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002248 // We can merge this new change in with the last one. Merging is
Dianne Hackborn40c87252014-03-19 16:55:40 -07002249 // allowed as long as only the states have changed, and within those states
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002250 // as long as no bit has changed both between now and the last entry, as
2251 // well as the last entry and the one before it (so we capture any toggles).
2252 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002253 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
2254 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
2255 mHistoryBufferLastPos = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002256 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002257 // If the last written history had a wakelock tag, we need to retain it.
2258 // Note that the condition above made sure that we aren't in a case where
2259 // both it and the current history item have a wakelock tag.
2260 if (mHistoryLastWritten.wakelockTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002261 cur.wakelockTag = cur.localWakelockTag;
2262 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002263 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002264 // If the last written history had a wake reason tag, we need to retain it.
2265 // Note that the condition above made sure that we aren't in a case where
2266 // both it and the current history item have a wakelock tag.
2267 if (mHistoryLastWritten.wakeReasonTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002268 cur.wakeReasonTag = cur.localWakeReasonTag;
2269 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002270 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002271 // If the last written history had an event, we need to retain it.
2272 // Note that the condition above made sure that we aren't in a case where
2273 // both it and the current history item have an event.
2274 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002275 cur.eventCode = mHistoryLastWritten.eventCode;
2276 cur.eventTag = cur.localEventTag;
2277 cur.eventTag.setTo(mHistoryLastWritten.eventTag);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002278 }
Dianne Hackborn1fadab52011-04-14 17:57:33 -07002279 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002280 }
2281
2282 final int dataSize = mHistoryBuffer.dataSize();
2283 if (dataSize >= MAX_HISTORY_BUFFER) {
2284 if (!mHistoryOverflow) {
2285 mHistoryOverflow = true;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002286 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
2287 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002288 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002289 }
2290
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002291 // After overflow, we allow various bit-wise states to settle to 0.
2292 boolean writeAnyway = false;
2293 final int curStates = cur.states & HistoryItem.SETTLE_TO_ZERO_STATES
2294 & mActiveHistoryStates;
2295 if (mHistoryLastWritten.states != curStates) {
2296 // mActiveHistoryStates keeps track of which bits in .states are now being
2297 // forced to 0.
2298 int old = mActiveHistoryStates;
2299 mActiveHistoryStates &= curStates | ~HistoryItem.SETTLE_TO_ZERO_STATES;
2300 writeAnyway |= old != mActiveHistoryStates;
2301 }
2302 final int curStates2 = cur.states2 & HistoryItem.SETTLE_TO_ZERO_STATES2
2303 & mActiveHistoryStates2;
2304 if (mHistoryLastWritten.states2 != curStates2) {
2305 // mActiveHistoryStates2 keeps track of which bits in .states2 are now being
2306 // forced to 0.
2307 int old = mActiveHistoryStates2;
2308 mActiveHistoryStates2 &= curStates2 | ~HistoryItem.SETTLE_TO_ZERO_STATES2;
2309 writeAnyway |= old != mActiveHistoryStates2;
2310 }
2311
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002312 // Once we've reached the maximum number of items, we only
2313 // record changes to the battery level and the most interesting states.
2314 // Once we've reached the maximum maximum number of items, we only
2315 // record changes to the battery level.
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002316 if (!writeAnyway && mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002317 (dataSize >= MAX_MAX_HISTORY_BUFFER
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002318 || ((mHistoryLastWritten.states^cur.states)
Dianne Hackborn3251b902014-06-20 14:40:53 -07002319 & HistoryItem.MOST_INTERESTING_STATES) == 0
2320 || ((mHistoryLastWritten.states2^cur.states2)
2321 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002322 return;
2323 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002324
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002325 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002326 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002327 }
2328
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002329 if (dataSize == 0) {
2330 // The history is currently empty; we need it to start with a time stamp.
2331 cur.currentTime = System.currentTimeMillis();
Dianne Hackborna7d0d552014-09-12 17:15:52 -07002332 mLastRecordedClockTime = cur.currentTime;
2333 mLastRecordedClockRealtime = elapsedRealtimeMs;
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002334 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur);
2335 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002336 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002337 }
2338
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002339 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
2340 HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002341 if (mIteratingHistory) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002342 throw new IllegalStateException("Can't do this while iterating history!");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002343 }
2344 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
2345 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002346 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002347 mHistoryLastWritten.states &= mActiveHistoryStates;
2348 mHistoryLastWritten.states2 &= mActiveHistoryStates2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002349 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07002350 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002351 cur.wakelockTag = null;
2352 cur.wakeReasonTag = null;
2353 cur.eventCode = HistoryItem.EVENT_NONE;
2354 cur.eventTag = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002355 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
2356 + " now " + mHistoryBuffer.dataPosition()
2357 + " size is now " + mHistoryBuffer.dataSize());
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002358 }
2359
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002360 int mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002361 int mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002362
Dianne Hackborn40c87252014-03-19 16:55:40 -07002363 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002364 if (mTrackRunningHistoryElapsedRealtime != 0) {
2365 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
2366 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
2367 if (diffUptime < (diffElapsed-20)) {
2368 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
2369 mHistoryAddTmp.setTo(mHistoryLastWritten);
2370 mHistoryAddTmp.wakelockTag = null;
2371 mHistoryAddTmp.wakeReasonTag = null;
2372 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
2373 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
2374 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
2375 }
2376 }
2377 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
2378 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
2379 mTrackRunningHistoryUptime = uptimeMs;
2380 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
2381 }
2382
2383 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
2384 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002385
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002386 if (!USE_OLD_HISTORY) {
2387 return;
2388 }
2389
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002390 if (!mHaveBatteryLevel || !mRecordingHistory) {
2391 return;
2392 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002393
2394 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002395 // and no states have since the last recorded entry changed and
2396 // are now resetting back to their original value, then just collapse
2397 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002398 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002399 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002400 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0
2401 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002402 // If the current is the same as the one before, then we no
2403 // longer need the entry.
2404 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002405 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002406 && mHistoryLastEnd.sameNonEvent(cur)) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002407 mHistoryLastEnd.next = null;
2408 mHistoryEnd.next = mHistoryCache;
2409 mHistoryCache = mHistoryEnd;
2410 mHistoryEnd = mHistoryLastEnd;
2411 mHistoryLastEnd = null;
2412 } else {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002413 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates);
2414 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002415 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002416 }
2417 return;
2418 }
2419
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002420 mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002421 mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002422
2423 if (mNumHistoryItems == MAX_HISTORY_ITEMS
2424 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002425 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002426 }
2427
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002428 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
2429 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002430 // record changes to the battery level and the most interesting states.
2431 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002432 // record changes to the battery level.
2433 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002434 == cur.batteryLevel &&
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002435 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002436 || ((mHistoryEnd.states^(cur.states&mActiveHistoryStates))
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002437 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002438 return;
2439 }
2440 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002441
Dianne Hackborn40c87252014-03-19 16:55:40 -07002442 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002443 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002444
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002445 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002446 String name, int uid) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002447 mHistoryCur.eventCode = code;
2448 mHistoryCur.eventTag = mHistoryCur.localEventTag;
2449 mHistoryCur.eventTag.string = name;
2450 mHistoryCur.eventTag.uid = uid;
Dianne Hackborn4590e522014-03-24 13:36:46 -07002451 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002452 }
2453
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002454 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002455 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002456 if (rec != null) {
2457 mHistoryCache = rec.next;
2458 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002459 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002460 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002461 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002462
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002463 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002464 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002465
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002466 void addHistoryRecordLocked(HistoryItem rec) {
2467 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002468 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002469 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002470 if (mHistoryEnd != null) {
2471 mHistoryEnd.next = rec;
2472 mHistoryEnd = rec;
2473 } else {
2474 mHistory = mHistoryEnd = rec;
2475 }
2476 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002477
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002478 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002479 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002480 if (USE_OLD_HISTORY) {
2481 if (mHistory != null) {
2482 mHistoryEnd.next = mHistoryCache;
2483 mHistoryCache = mHistory;
2484 mHistory = mHistoryLastEnd = mHistoryEnd = null;
2485 }
2486 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002487 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002488
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002489 mHistoryBaseTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002490 mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002491 mTrackRunningHistoryElapsedRealtime = 0;
2492 mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002493
2494 mHistoryBuffer.setDataSize(0);
2495 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002496 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002497 mHistoryLastLastWritten.clear();
2498 mHistoryLastWritten.clear();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002499 mHistoryTagPool.clear();
2500 mNextHistoryTagIdx = 0;
2501 mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002502 mHistoryBufferLastPos = -1;
2503 mHistoryOverflow = false;
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002504 mActiveHistoryStates = 0xffffffff;
2505 mActiveHistoryStates2 = 0xffffffff;
Dianne Hackborna7d0d552014-09-12 17:15:52 -07002506 mLastRecordedClockTime = 0;
2507 mLastRecordedClockRealtime = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002508 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002509
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002510 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
2511 long realtime) {
Adam Lesinskie283d332015-04-16 12:29:25 -07002512 mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002513
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002514 boolean unpluggedScreenOff = unplugged && screenOff;
2515 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
2516 updateKernelWakelocksLocked();
2517 requestWakelockCpuUpdate();
2518 if (!unpluggedScreenOff) {
2519 // We are switching to no longer tracking wake locks, but we want
2520 // the next CPU update we receive to take them in to account.
2521 mDistributeWakelockCpu = true;
2522 }
2523 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002524 }
2525 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002526
Dianne Hackborn099bc622014-01-22 13:39:16 -08002527 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
2528 mIsolatedUids.put(isolatedUid, appUid);
2529 }
2530
2531 public void removeIsolatedUidLocked(int isolatedUid, int appUid) {
2532 int curUid = mIsolatedUids.get(isolatedUid, -1);
2533 if (curUid == appUid) {
2534 mIsolatedUids.delete(isolatedUid);
2535 }
2536 }
2537
2538 public int mapUid(int uid) {
2539 int isolated = mIsolatedUids.get(uid, -1);
2540 return isolated > 0 ? isolated : uid;
2541 }
2542
2543 public void noteEventLocked(int code, String name, int uid) {
2544 uid = mapUid(uid);
Dianne Hackborn37de0982014-05-09 09:32:18 -07002545 if (!mActiveEvents.updateState(code, name, uid, 0)) {
2546 return;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002547 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07002548 final long elapsedRealtime = SystemClock.elapsedRealtime();
2549 final long uptime = SystemClock.uptimeMillis();
2550 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002551 }
2552
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07002553 public void noteCurrentTimeChangedLocked() {
2554 final long currentTime = System.currentTimeMillis();
2555 final long elapsedRealtime = SystemClock.elapsedRealtime();
2556 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborna7d0d552014-09-12 17:15:52 -07002557 if (isStartClockTimeValid()) {
2558 // Has the time changed sufficiently that it is really worth recording?
2559 if (mLastRecordedClockTime != 0) {
2560 long expectedClockTime = mLastRecordedClockTime
2561 + (elapsedRealtime - mLastRecordedClockRealtime);
2562 if (currentTime >= (expectedClockTime-500)
2563 && currentTime <= (expectedClockTime+500)) {
2564 // Not sufficiently changed, skip!
2565 return;
2566 }
2567 }
2568 }
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07002569 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
2570 if (isStartClockTimeValid()) {
2571 mStartClockTime = currentTime;
2572 }
2573 }
2574
Dianne Hackborn61659e52014-07-09 16:13:01 -07002575 public void noteProcessStartLocked(String name, int uid) {
2576 uid = mapUid(uid);
2577 if (isOnBattery()) {
2578 Uid u = getUidStatsLocked(uid);
2579 u.getProcessStatsLocked(name).incStartsLocked();
2580 }
2581 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) {
2582 return;
2583 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002584 if (!mRecordAllHistory) {
2585 return;
2586 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07002587 final long elapsedRealtime = SystemClock.elapsedRealtime();
2588 final long uptime = SystemClock.uptimeMillis();
2589 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid);
2590 }
2591
Dianne Hackborn1e01d162014-12-04 17:46:42 -08002592 public void noteProcessCrashLocked(String name, int uid) {
2593 uid = mapUid(uid);
2594 if (isOnBattery()) {
2595 Uid u = getUidStatsLocked(uid);
2596 u.getProcessStatsLocked(name).incNumCrashesLocked();
2597 }
2598 }
2599
2600 public void noteProcessAnrLocked(String name, int uid) {
2601 uid = mapUid(uid);
2602 if (isOnBattery()) {
2603 Uid u = getUidStatsLocked(uid);
2604 u.getProcessStatsLocked(name).incNumAnrsLocked();
2605 }
2606 }
2607
Dianne Hackborn61659e52014-07-09 16:13:01 -07002608 public void noteProcessStateLocked(String name, int uid, int state) {
2609 uid = mapUid(uid);
2610 final long elapsedRealtime = SystemClock.elapsedRealtime();
2611 getUidStatsLocked(uid).updateProcessStateLocked(name, state, elapsedRealtime);
2612 }
2613
2614 public void noteProcessFinishLocked(String name, int uid) {
2615 uid = mapUid(uid);
2616 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) {
2617 return;
2618 }
2619 final long elapsedRealtime = SystemClock.elapsedRealtime();
2620 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn61659e52014-07-09 16:13:01 -07002621 getUidStatsLocked(uid).updateProcessStateLocked(name, Uid.PROCESS_STATE_NONE,
2622 elapsedRealtime);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002623 if (!mRecordAllHistory) {
2624 return;
2625 }
2626 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid);
Dianne Hackborn61659e52014-07-09 16:13:01 -07002627 }
2628
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002629 public void noteSyncStartLocked(String name, int uid) {
2630 uid = mapUid(uid);
2631 final long elapsedRealtime = SystemClock.elapsedRealtime();
2632 final long uptime = SystemClock.uptimeMillis();
2633 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime);
2634 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
2635 return;
2636 }
2637 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid);
2638 }
2639
2640 public void noteSyncFinishLocked(String name, int uid) {
2641 uid = mapUid(uid);
2642 final long elapsedRealtime = SystemClock.elapsedRealtime();
2643 final long uptime = SystemClock.uptimeMillis();
2644 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime);
2645 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
2646 return;
2647 }
2648 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid);
2649 }
2650
2651 public void noteJobStartLocked(String name, int uid) {
2652 uid = mapUid(uid);
2653 final long elapsedRealtime = SystemClock.elapsedRealtime();
2654 final long uptime = SystemClock.uptimeMillis();
2655 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime);
2656 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
2657 return;
2658 }
2659 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid);
2660 }
2661
2662 public void noteJobFinishLocked(String name, int uid) {
2663 uid = mapUid(uid);
2664 final long elapsedRealtime = SystemClock.elapsedRealtime();
2665 final long uptime = SystemClock.uptimeMillis();
2666 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime);
2667 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
2668 return;
2669 }
2670 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid);
2671 }
2672
Dianne Hackborn1e383822015-04-10 14:02:33 -07002673 public void noteAlarmStartLocked(String name, int uid) {
2674 if (!mRecordAllHistory) {
2675 return;
2676 }
2677 uid = mapUid(uid);
2678 final long elapsedRealtime = SystemClock.elapsedRealtime();
2679 final long uptime = SystemClock.uptimeMillis();
2680 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_START, name, uid, 0)) {
2681 return;
2682 }
2683 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid);
2684 }
2685
2686 public void noteAlarmFinishLocked(String name, int uid) {
2687 if (!mRecordAllHistory) {
2688 return;
2689 }
2690 uid = mapUid(uid);
2691 final long elapsedRealtime = SystemClock.elapsedRealtime();
2692 final long uptime = SystemClock.uptimeMillis();
2693 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) {
2694 return;
2695 }
2696 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid);
2697 }
2698
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002699 private void requestWakelockCpuUpdate() {
2700 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
2701 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
2702 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
2703 }
2704 }
2705
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002706 private void requestImmediateCpuUpdate() {
2707 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2708 mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS);
2709 }
2710
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002711 public void setRecordAllHistoryLocked(boolean enabled) {
2712 mRecordAllHistory = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002713 if (!enabled) {
2714 // Clear out any existing state.
2715 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK);
Dianne Hackborn1e383822015-04-10 14:02:33 -07002716 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002717 // Record the currently running processes as stopping, now that we are no
2718 // longer tracking them.
2719 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
2720 HistoryItem.EVENT_PROC);
2721 if (active != null) {
2722 long mSecRealtime = SystemClock.elapsedRealtime();
2723 final long mSecUptime = SystemClock.uptimeMillis();
2724 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
2725 SparseIntArray uids = ent.getValue();
2726 for (int j=0; j<uids.size(); j++) {
2727 addHistoryEventLocked(mSecRealtime, mSecUptime,
2728 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j));
2729 }
2730 }
2731 }
2732 } else {
2733 // Record the currently running processes as starting, now that we are tracking them.
2734 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
2735 HistoryItem.EVENT_PROC);
2736 if (active != null) {
2737 long mSecRealtime = SystemClock.elapsedRealtime();
2738 final long mSecUptime = SystemClock.uptimeMillis();
2739 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
2740 SparseIntArray uids = ent.getValue();
2741 for (int j=0; j<uids.size(); j++) {
2742 addHistoryEventLocked(mSecRealtime, mSecUptime,
2743 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j));
2744 }
2745 }
2746 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002747 }
2748 }
2749
Dianne Hackborn9a755432014-05-15 17:05:22 -07002750 public void setNoAutoReset(boolean enabled) {
2751 mNoAutoReset = enabled;
2752 }
2753
2754 private String mInitialAcquireWakeName;
2755 private int mInitialAcquireWakeUid = -1;
2756
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002757 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002758 boolean unimportantForLogging, long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002759 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002760 if (type == WAKE_TYPE_PARTIAL) {
2761 // Only care about partial wake locks, since full wake locks
2762 // will be canceled when the user puts the screen to sleep.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002763 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002764 if (historyName == null) {
2765 historyName = name;
2766 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002767 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002768 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
2769 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002770 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002771 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002772 }
2773 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002774 if (mWakeLockNesting == 0) {
2775 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
2776 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
2777 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002778 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002779 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002780 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002781 mWakeLockImportant = !unimportantForLogging;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002782 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002783 } else if (!mWakeLockImportant && !unimportantForLogging
2784 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002785 if (mHistoryLastWritten.wakelockTag != null) {
2786 // We'll try to update the last tag.
2787 mHistoryLastWritten.wakelockTag = null;
2788 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002789 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002790 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002791 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002792 }
2793 mWakeLockImportant = true;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002794 }
2795 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002796 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002797 if (uid >= 0) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002798 //if (uid == 0) {
2799 // Slog.wtf(TAG, "Acquiring wake lock from root: " + name);
2800 //}
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002801 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002802 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002803 }
2804 }
2805
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002806 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type,
2807 long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002808 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002809 if (type == WAKE_TYPE_PARTIAL) {
2810 mWakeLockNesting--;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002811 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002812 if (historyName == null) {
2813 historyName = name;
2814 }
2815 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
2816 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002817 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002818 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002819 }
2820 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002821 if (mWakeLockNesting == 0) {
2822 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
2823 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
2824 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn37de0982014-05-09 09:32:18 -07002825 mInitialAcquireWakeName = null;
2826 mInitialAcquireWakeUid = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002827 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002828 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002829 }
2830 if (uid >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002831 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002832 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002833 }
2834 }
2835
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002836 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
2837 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002838 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002839 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002840 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002841 for (int i=0; i<N; i++) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002842 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002843 elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002844 }
2845 }
2846
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002847 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
2848 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002849 String newHistoryName, int newType, boolean newUnimportantForLogging) {
2850 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002851 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002852 // For correct semantics, we start the need worksources first, so that we won't
2853 // make inappropriate history items as if all wake locks went away and new ones
2854 // appeared. This is okay because tracking of wake locks allows nesting.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002855 final int NN = newWs.size();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002856 for (int i=0; i<NN; i++) {
2857 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002858 newUnimportantForLogging, elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002859 }
2860 final int NO = ws.size();
2861 for (int i=0; i<NO; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002862 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002863 }
2864 }
2865
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002866 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
2867 String historyName, int type) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002868 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002869 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002870 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002871 for (int i=0; i<N; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002872 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002873 }
2874 }
2875
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002876 void aggregateLastWakeupUptimeLocked(long uptimeMs) {
2877 if (mLastWakeupReason != null) {
2878 long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002879 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
2880 timer.addCurrentReportedCount(1);
2881 timer.addCurrentReportedTotalTime(deltaUptime * 1000); // time is in microseconds
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002882 mLastWakeupReason = null;
2883 }
2884 }
2885
2886 public void noteWakeupReasonLocked(String reason) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002887 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002888 final long uptime = SystemClock.uptimeMillis();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002889 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": "
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002890 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002891 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002892 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
2893 mHistoryCur.wakeReasonTag.string = reason;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002894 mHistoryCur.wakeReasonTag.uid = 0;
2895 mLastWakeupReason = reason;
2896 mLastWakeupUptimeMs = uptime;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002897 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002898 }
2899
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002900 public int startAddingCpuLocked() {
2901 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2902
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002903 if (!mOnBatteryInternal) {
2904 return -1;
2905 }
2906
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002907 final int N = mPartialTimers.size();
2908 if (N == 0) {
2909 mLastPartialTimers.clear();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002910 mDistributeWakelockCpu = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002911 return 0;
2912 }
2913
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002914 if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) {
2915 return 0;
2916 }
2917
2918 mDistributeWakelockCpu = false;
2919
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002920 // How many timers should consume CPU? Only want to include ones
2921 // that have already been in the list.
2922 for (int i=0; i<N; i++) {
2923 StopwatchTimer st = mPartialTimers.get(i);
2924 if (st.mInList) {
2925 Uid uid = st.mUid;
2926 // We don't include the system UID, because it so often
2927 // holds wake locks at one request or another of an app.
2928 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2929 return 50;
2930 }
2931 }
2932 }
2933
2934 return 0;
2935 }
2936
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002937 public void finishAddingCpuLocked(int perc, int remainUTime, int remainSTtime,
2938 int totalUTime, int totalSTime, int statUserTime, int statSystemTime,
2939 int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime,
2940 long[] cpuSpeedTimes) {
2941 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
2942 + " user=" + statUserTime + " sys=" + statSystemTime
2943 + " io=" + statIOWaitTime + " irq=" + statIrqTime
2944 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime);
2945 mCurStepCpuUserTime += totalUTime;
2946 mCurStepCpuSystemTime += totalSTime;
2947 mCurStepStatUserTime += statUserTime;
2948 mCurStepStatSystemTime += statSystemTime;
2949 mCurStepStatIOWaitTime += statIOWaitTime;
2950 mCurStepStatIrqTime += statIrqTime;
2951 mCurStepStatSoftIrqTime += statSoftIrqTime;
2952 mCurStepStatIdleTime += statIdleTime;
2953
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002954 final int N = mPartialTimers.size();
2955 if (perc != 0) {
2956 int num = 0;
2957 for (int i=0; i<N; i++) {
2958 StopwatchTimer st = mPartialTimers.get(i);
2959 if (st.mInList) {
2960 Uid uid = st.mUid;
2961 // We don't include the system UID, because it so often
2962 // holds wake locks at one request or another of an app.
2963 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2964 num++;
2965 }
2966 }
2967 }
2968 if (num != 0) {
2969 for (int i=0; i<N; i++) {
2970 StopwatchTimer st = mPartialTimers.get(i);
2971 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002972 Uid uid = st.mUid;
2973 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002974 int myUTime = remainUTime/num;
2975 int mySTime = remainSTtime/num;
2976 remainUTime -= myUTime;
2977 remainSTtime -= mySTime;
Dianne Hackborn618b8c12010-09-09 23:10:38 -07002978 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002979 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002980 proc.addCpuTimeLocked(myUTime, mySTime, cpuSpeedTimes);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002981 }
2982 }
2983 }
2984 }
2985
2986 // Just in case, collect any lost CPU time.
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002987 if (remainUTime != 0 || remainSTtime != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002988 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
2989 if (uid != null) {
2990 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002991 proc.addCpuTimeLocked(remainUTime, remainSTtime, cpuSpeedTimes);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002992 }
2993 }
2994 }
2995
2996 final int NL = mLastPartialTimers.size();
2997 boolean diff = N != NL;
2998 for (int i=0; i<NL && !diff; i++) {
2999 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
3000 }
3001 if (!diff) {
3002 for (int i=0; i<NL; i++) {
3003 mPartialTimers.get(i).mInList = true;
3004 }
3005 return;
3006 }
3007
3008 for (int i=0; i<NL; i++) {
3009 mLastPartialTimers.get(i).mInList = false;
3010 }
3011 mLastPartialTimers.clear();
3012 for (int i=0; i<N; i++) {
3013 StopwatchTimer st = mPartialTimers.get(i);
3014 st.mInList = true;
3015 mLastPartialTimers.add(st);
3016 }
3017 }
3018
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003019 public void noteProcessDiedLocked(int uid, int pid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003020 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003021 Uid u = mUidStats.get(uid);
3022 if (u != null) {
3023 u.mPids.remove(pid);
3024 }
3025 }
3026
3027 public long getProcessWakeTime(int uid, int pid, long realtime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003028 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003029 Uid u = mUidStats.get(uid);
3030 if (u != null) {
3031 Uid.Pid p = u.mPids.get(pid);
3032 if (p != null) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003033 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003034 }
3035 }
3036 return 0;
3037 }
3038
3039 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003040 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003041 Uid u = mUidStats.get(uid);
3042 if (u != null) {
3043 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
3044 }
3045 }
3046
Dianne Hackborn287952c2010-09-22 22:34:31 -07003047 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003048 uid = mapUid(uid);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003049 Uid u = mUidStats.get(uid);
3050 if (u != null) {
3051 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
3052 }
3053 }
3054
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003055 int mSensorNesting;
3056
3057 public void noteStartSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003058 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003059 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003060 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003061 if (mSensorNesting == 0) {
3062 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
3063 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
3064 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003065 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003066 }
3067 mSensorNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003068 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003069 }
3070
3071 public void noteStopSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003072 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003073 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003074 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003075 mSensorNesting--;
3076 if (mSensorNesting == 0) {
3077 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
3078 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
3079 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003080 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003081 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003082 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003083 }
3084
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003085 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003086
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003087 public void noteStartGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003088 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003089 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003090 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003091 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003092 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003093 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
3094 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003095 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003096 }
3097 mGpsNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003098 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003099 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003100
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003101 public void noteStopGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003102 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003103 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003104 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003105 mGpsNesting--;
3106 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003107 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003108 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
3109 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003110 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003111 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003112 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003113 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003114
Jeff Browne95c3cd2014-05-02 16:59:26 -07003115 public void noteScreenStateLocked(int state) {
3116 if (mScreenState != state) {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08003117 recordDailyStatsIfNeededLocked(true);
Jeff Browne95c3cd2014-05-02 16:59:26 -07003118 final int oldState = mScreenState;
3119 mScreenState = state;
3120 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
3121 + ", newState=" + Display.stateToString(state));
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003122
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003123 if (state != Display.STATE_UNKNOWN) {
3124 int stepState = state-1;
3125 if (stepState < 4) {
3126 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState;
3127 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_SCREEN_STATE) | stepState;
3128 } else {
3129 Slog.wtf(TAG, "Unexpected screen state: " + state);
3130 }
3131 }
3132
Jeff Browne95c3cd2014-05-02 16:59:26 -07003133 if (state == Display.STATE_ON) {
3134 // Screen turning on.
3135 final long elapsedRealtime = SystemClock.elapsedRealtime();
3136 final long uptime = SystemClock.uptimeMillis();
3137 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
3138 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
3139 + Integer.toHexString(mHistoryCur.states));
3140 addHistoryRecordLocked(elapsedRealtime, uptime);
3141 mScreenOnTimer.startRunningLocked(elapsedRealtime);
3142 if (mScreenBrightnessBin >= 0) {
3143 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
3144 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003145
Jeff Browne95c3cd2014-05-02 16:59:26 -07003146 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false,
3147 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003148
Jeff Browne95c3cd2014-05-02 16:59:26 -07003149 // Fake a wake lock, so we consider the device waked as long
3150 // as the screen is on.
3151 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
3152 elapsedRealtime, uptime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003153
Jeff Browne95c3cd2014-05-02 16:59:26 -07003154 // Update discharge amounts.
3155 if (mOnBatteryInternal) {
3156 updateDischargeScreenLevelsLocked(false, true);
3157 }
3158 } else if (oldState == Display.STATE_ON) {
3159 // Screen turning off or dozing.
3160 final long elapsedRealtime = SystemClock.elapsedRealtime();
3161 final long uptime = SystemClock.uptimeMillis();
3162 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
3163 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
3164 + Integer.toHexString(mHistoryCur.states));
3165 addHistoryRecordLocked(elapsedRealtime, uptime);
3166 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
3167 if (mScreenBrightnessBin >= 0) {
3168 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
3169 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003170
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003171 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL,
Jeff Browne95c3cd2014-05-02 16:59:26 -07003172 elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003173
Jeff Browne95c3cd2014-05-02 16:59:26 -07003174 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
3175 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003176
Jeff Browne95c3cd2014-05-02 16:59:26 -07003177 // Update discharge amounts.
3178 if (mOnBatteryInternal) {
3179 updateDischargeScreenLevelsLocked(true, false);
3180 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08003181 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07003182 }
3183 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003184
Dianne Hackborn617f8772009-03-31 15:04:46 -07003185 public void noteScreenBrightnessLocked(int brightness) {
3186 // Bin the brightness.
3187 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
3188 if (bin < 0) bin = 0;
3189 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
3190 if (mScreenBrightnessBin != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003191 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003192 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003193 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
3194 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003195 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
3196 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003197 addHistoryRecordLocked(elapsedRealtime, uptime);
Jeff Browne95c3cd2014-05-02 16:59:26 -07003198 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003199 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003200 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003201 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003202 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003203 }
3204 mScreenBrightnessBin = bin;
3205 }
3206 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003207
Dianne Hackborn617f8772009-03-31 15:04:46 -07003208 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003209 if (mOnBatteryInternal) {
3210 uid = mapUid(uid);
3211 getUidStatsLocked(uid).noteUserActivityLocked(event);
3212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003213 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003214
Jeff Browne95c3cd2014-05-02 16:59:26 -07003215 public void noteInteractiveLocked(boolean interactive) {
3216 if (mInteractive != interactive) {
3217 final long elapsedRealtime = SystemClock.elapsedRealtime();
3218 mInteractive = interactive;
3219 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
3220 if (interactive) {
3221 mInteractiveTimer.startRunningLocked(elapsedRealtime);
3222 } else {
3223 mInteractiveTimer.stopRunningLocked(elapsedRealtime);
3224 }
3225 }
3226 }
3227
Dianne Hackborn1e01d162014-12-04 17:46:42 -08003228 public void noteConnectivityChangedLocked(int type, String extra) {
3229 final long elapsedRealtime = SystemClock.elapsedRealtime();
3230 final long uptime = SystemClock.uptimeMillis();
3231 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
3232 extra, type);
3233 mNumConnectivityChange++;
3234 }
3235
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003236 public void noteMobileRadioPowerState(int powerState, long timestampNs) {
3237 final long elapsedRealtime = SystemClock.elapsedRealtime();
3238 final long uptime = SystemClock.uptimeMillis();
3239 if (mMobileRadioPowerState != powerState) {
3240 long realElapsedRealtimeMs;
3241 final boolean active =
3242 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
3243 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
3244 if (active) {
Dianne Hackbornf7097a52014-05-13 09:56:14 -07003245 mMobileRadioActiveStartTime = realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003246 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
3247 } else {
3248 realElapsedRealtimeMs = timestampNs / (1000*1000);
Dianne Hackbornf7097a52014-05-13 09:56:14 -07003249 long lastUpdateTimeMs = mMobileRadioActiveStartTime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003250 if (realElapsedRealtimeMs < lastUpdateTimeMs) {
3251 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
3252 + " is before start time " + lastUpdateTimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003253 realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003254 } else if (realElapsedRealtimeMs < elapsedRealtime) {
3255 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
3256 - realElapsedRealtimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003257 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003258 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
3259 }
3260 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
3261 + Integer.toHexString(mHistoryCur.states));
3262 addHistoryRecordLocked(elapsedRealtime, uptime);
3263 mMobileRadioPowerState = powerState;
3264 if (active) {
3265 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
3266 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
3267 } else {
3268 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003269 updateMobileRadioStateLocked(realElapsedRealtimeMs);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003270 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003271 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003272 }
3273 }
3274
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003275 public void notePowerSaveMode(boolean enabled) {
3276 if (mPowerSaveModeEnabled != enabled) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003277 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0;
3278 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState;
3279 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003280 final long elapsedRealtime = SystemClock.elapsedRealtime();
3281 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003282 mPowerSaveModeEnabled = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003283 if (enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003284 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
3285 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003286 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003287 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003288 } else {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003289 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
3290 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003291 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003292 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003293 }
3294 addHistoryRecordLocked(elapsedRealtime, uptime);
3295 }
3296 }
3297
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003298 public void noteDeviceIdleModeLocked(boolean enabled, boolean fromActive, boolean fromMotion) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003299 final long elapsedRealtime = SystemClock.elapsedRealtime();
3300 final long uptime = SystemClock.uptimeMillis();
3301 boolean nowIdling = enabled;
3302 if (mDeviceIdling && !enabled && !fromActive && !fromMotion) {
3303 // We don't go out of general idling mode until explicitly taken out of
3304 // device idle through going active or significant motion.
3305 nowIdling = true;
3306 }
3307 if (mDeviceIdling != nowIdling) {
3308 mDeviceIdling = nowIdling;
3309 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0;
3310 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState;
3311 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState;
3312 if (enabled) {
3313 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime);
3314 } else {
3315 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime);
3316 }
3317 }
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003318 if (mDeviceIdleModeEnabled != enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003319 mDeviceIdleModeEnabled = enabled;
3320 if (fromMotion) {
3321 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SIGNIFICANT_MOTION,
3322 "", 0);
3323 }
3324 if (fromActive) {
3325 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
3326 "", 0);
3327 }
3328 if (enabled) {
3329 mHistoryCur.states2 |= HistoryItem.STATE2_DEVICE_IDLE_FLAG;
3330 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode enabled to: "
3331 + Integer.toHexString(mHistoryCur.states2));
3332 mDeviceIdleModeEnabledTimer.startRunningLocked(elapsedRealtime);
3333 } else {
3334 mHistoryCur.states2 &= ~HistoryItem.STATE2_DEVICE_IDLE_FLAG;
3335 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode disabled to: "
3336 + Integer.toHexString(mHistoryCur.states2));
3337 mDeviceIdleModeEnabledTimer.stopRunningLocked(elapsedRealtime);
3338 }
3339 addHistoryRecordLocked(elapsedRealtime, uptime);
3340 }
3341 }
3342
3343 public void notePackageInstalledLocked(String pkgName, int versionCode) {
3344 final long elapsedRealtime = SystemClock.elapsedRealtime();
3345 final long uptime = SystemClock.uptimeMillis();
3346 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED,
3347 pkgName, versionCode);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003348 PackageChange pc = new PackageChange();
3349 pc.mPackageName = pkgName;
3350 pc.mUpdate = true;
3351 pc.mVersionCode = versionCode;
3352 addPackageChange(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003353 }
3354
3355 public void notePackageUninstalledLocked(String pkgName) {
3356 final long elapsedRealtime = SystemClock.elapsedRealtime();
3357 final long uptime = SystemClock.uptimeMillis();
3358 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
3359 pkgName, 0);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003360 PackageChange pc = new PackageChange();
3361 pc.mPackageName = pkgName;
3362 pc.mUpdate = true;
3363 addPackageChange(pc);
3364 }
3365
3366 private void addPackageChange(PackageChange pc) {
3367 if (mDailyPackageChanges == null) {
3368 mDailyPackageChanges = new ArrayList<>();
3369 }
3370 mDailyPackageChanges.add(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003371 }
3372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373 public void notePhoneOnLocked() {
3374 if (!mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003375 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003376 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003377 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003378 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
3379 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003380 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 mPhoneOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003382 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003383 }
3384 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003386 public void notePhoneOffLocked() {
3387 if (mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003388 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003389 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003390 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003391 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
3392 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003393 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 mPhoneOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003395 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003396 }
3397 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003398
Dianne Hackborn3251b902014-06-20 14:40:53 -07003399 void stopAllPhoneSignalStrengthTimersLocked(int except) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003400 final long elapsedRealtime = SystemClock.elapsedRealtime();
Wink Saville52840902011-02-18 12:40:47 -08003401 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003402 if (i == except) {
3403 continue;
3404 }
3405 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003406 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003407 }
3408 }
3409 }
3410
Dianne Hackborne4a59512010-12-07 11:08:07 -08003411 private int fixPhoneServiceState(int state, int signalBin) {
3412 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
3413 // In this case we will always be STATE_OUT_OF_SERVICE, so need
3414 // to infer that we are scanning from other data.
3415 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08003416 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003417 state = ServiceState.STATE_IN_SERVICE;
3418 }
3419 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003420
Dianne Hackborne4a59512010-12-07 11:08:07 -08003421 return state;
3422 }
3423
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003424 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003425 boolean scanning = false;
3426 boolean newHistory = false;
3427
3428 mPhoneServiceStateRaw = state;
3429 mPhoneSimStateRaw = simState;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003430 mPhoneSignalStrengthBinRaw = strengthBin;
3431
3432 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003433 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne4a59512010-12-07 11:08:07 -08003434
3435 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
3436 // In this case we will always be STATE_OUT_OF_SERVICE, so need
3437 // to infer that we are scanning from other data.
3438 if (state == ServiceState.STATE_OUT_OF_SERVICE
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003439 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003440 state = ServiceState.STATE_IN_SERVICE;
3441 }
3442 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003443
3444 // If the phone is powered off, stop all timers.
3445 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003446 strengthBin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07003447
Dianne Hackborne4a59512010-12-07 11:08:07 -08003448 // If we are in service, make sure the correct signal string timer is running.
3449 } else if (state == ServiceState.STATE_IN_SERVICE) {
3450 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003451
3452 // If we're out of service, we are in the lowest signal strength
3453 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07003454 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003455 scanning = true;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003456 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07003457 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003458 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08003459 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003460 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
3461 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003462 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
Amith Yamasanif37447b2009-10-08 18:28:01 -07003463 }
3464 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003465
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003466 if (!scanning) {
3467 // If we are no longer scanning, then stop the scanning timer.
3468 if (mPhoneSignalScanningTimer.isRunningLocked()) {
3469 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
3470 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
3471 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08003472 newHistory = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003473 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003474 }
3475 }
3476
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003477 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003478 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
3479 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003480 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003481 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08003482 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003483 mPhoneServiceState = state;
3484 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08003485
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003486 if (mPhoneSignalStrengthBin != strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003487 if (mPhoneSignalStrengthBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003488 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003489 elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003490 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003491 if (strengthBin >= 0) {
3492 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003493 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003494 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07003495 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
3496 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003497 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
Dianne Hackborne4a59512010-12-07 11:08:07 -08003498 + Integer.toHexString(mHistoryCur.states));
3499 newHistory = true;
3500 } else {
Dianne Hackborn3251b902014-06-20 14:40:53 -07003501 stopAllPhoneSignalStrengthTimersLocked(-1);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003502 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003503 mPhoneSignalStrengthBin = strengthBin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08003504 }
3505
3506 if (newHistory) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07003507 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003508 }
3509 }
3510
3511 /**
3512 * Telephony stack updates the phone state.
3513 * @param state phone state from ServiceState.getState()
3514 */
3515 public void notePhoneStateLocked(int state, int simState) {
3516 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003517 }
3518
Wink Savillee9b06d72009-05-18 21:47:50 -07003519 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07003520 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08003521 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08003522 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003523 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003524
Dianne Hackborn627bba72009-03-24 22:32:56 -07003525 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
3526 int bin = DATA_CONNECTION_NONE;
3527 if (hasData) {
3528 switch (dataType) {
3529 case TelephonyManager.NETWORK_TYPE_EDGE:
3530 bin = DATA_CONNECTION_EDGE;
3531 break;
3532 case TelephonyManager.NETWORK_TYPE_GPRS:
3533 bin = DATA_CONNECTION_GPRS;
3534 break;
3535 case TelephonyManager.NETWORK_TYPE_UMTS:
3536 bin = DATA_CONNECTION_UMTS;
3537 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003538 case TelephonyManager.NETWORK_TYPE_CDMA:
3539 bin = DATA_CONNECTION_CDMA;
3540 break;
3541 case TelephonyManager.NETWORK_TYPE_EVDO_0:
3542 bin = DATA_CONNECTION_EVDO_0;
3543 break;
3544 case TelephonyManager.NETWORK_TYPE_EVDO_A:
3545 bin = DATA_CONNECTION_EVDO_A;
3546 break;
3547 case TelephonyManager.NETWORK_TYPE_1xRTT:
3548 bin = DATA_CONNECTION_1xRTT;
3549 break;
3550 case TelephonyManager.NETWORK_TYPE_HSDPA:
3551 bin = DATA_CONNECTION_HSDPA;
3552 break;
3553 case TelephonyManager.NETWORK_TYPE_HSUPA:
3554 bin = DATA_CONNECTION_HSUPA;
3555 break;
3556 case TelephonyManager.NETWORK_TYPE_HSPA:
3557 bin = DATA_CONNECTION_HSPA;
3558 break;
3559 case TelephonyManager.NETWORK_TYPE_IDEN:
3560 bin = DATA_CONNECTION_IDEN;
3561 break;
3562 case TelephonyManager.NETWORK_TYPE_EVDO_B:
3563 bin = DATA_CONNECTION_EVDO_B;
3564 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07003565 case TelephonyManager.NETWORK_TYPE_LTE:
3566 bin = DATA_CONNECTION_LTE;
3567 break;
3568 case TelephonyManager.NETWORK_TYPE_EHRPD:
3569 bin = DATA_CONNECTION_EHRPD;
3570 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08003571 case TelephonyManager.NETWORK_TYPE_HSPAP:
3572 bin = DATA_CONNECTION_HSPAP;
3573 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07003574 default:
3575 bin = DATA_CONNECTION_OTHER;
3576 break;
3577 }
3578 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003579 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003580 if (mPhoneDataConnectionType != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003581 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003582 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003583 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
3584 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003585 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
3586 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003587 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003588 if (mPhoneDataConnectionType >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003589 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003590 elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003591 }
3592 mPhoneDataConnectionType = bin;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003593 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003594 }
3595 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003596
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003597 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07003598 if (!mWifiOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003599 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003600 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003601 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003602 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
3603 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003604 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003605 mWifiOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003606 mWifiOnTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003607 scheduleSyncExternalStatsLocked("wifi-off");
The Android Open Source Project10592532009-03-18 17:39:46 -07003608 }
3609 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003610
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003611 public void noteWifiOffLocked() {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003612 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003613 final long uptime = SystemClock.uptimeMillis();
The Android Open Source Project10592532009-03-18 17:39:46 -07003614 if (mWifiOn) {
Dianne Hackborn3251b902014-06-20 14:40:53 -07003615 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003616 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
3617 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003618 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003619 mWifiOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003620 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003621 scheduleSyncExternalStatsLocked("wifi-on");
The Android Open Source Project10592532009-03-18 17:39:46 -07003622 }
3623 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003624
3625 public void noteAudioOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003626 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003627 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003628 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003629 if (mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003630 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003631 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
3632 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003633 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003634 mAudioOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003635 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003636 mAudioOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003637 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003638 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003639
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003640 public void noteAudioOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003641 if (mAudioOnNesting == 0) {
3642 return;
3643 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003644 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003645 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003646 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003647 if (--mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003648 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003649 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3650 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003651 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003652 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003653 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003654 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003655 }
3656
3657 public void noteVideoOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003658 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003659 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003660 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003661 if (mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003662 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003663 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
3664 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003665 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003666 mVideoOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003667 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003668 mVideoOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003669 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003670 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003671
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003672 public void noteVideoOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003673 if (mVideoOnNesting == 0) {
3674 return;
3675 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003676 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003677 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003678 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003679 if (--mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003680 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003681 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3682 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003683 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003684 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003685 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003686 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003687 }
3688
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003689 public void noteResetAudioLocked() {
3690 if (mAudioOnNesting > 0) {
3691 final long elapsedRealtime = SystemClock.elapsedRealtime();
3692 final long uptime = SystemClock.uptimeMillis();
3693 mAudioOnNesting = 0;
3694 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
3695 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3696 + Integer.toHexString(mHistoryCur.states));
3697 addHistoryRecordLocked(elapsedRealtime, uptime);
3698 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime);
3699 for (int i=0; i<mUidStats.size(); i++) {
3700 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3701 uid.noteResetAudioLocked(elapsedRealtime);
3702 }
3703 }
3704 }
3705
3706 public void noteResetVideoLocked() {
3707 if (mVideoOnNesting > 0) {
3708 final long elapsedRealtime = SystemClock.elapsedRealtime();
3709 final long uptime = SystemClock.uptimeMillis();
3710 mAudioOnNesting = 0;
3711 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
3712 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3713 + Integer.toHexString(mHistoryCur.states));
3714 addHistoryRecordLocked(elapsedRealtime, uptime);
3715 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime);
3716 for (int i=0; i<mUidStats.size(); i++) {
3717 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3718 uid.noteResetVideoLocked(elapsedRealtime);
3719 }
3720 }
3721 }
3722
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003723 public void noteActivityResumedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003724 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003725 getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003726 }
3727
3728 public void noteActivityPausedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003729 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003730 getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003731 }
3732
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003733 public void noteVibratorOnLocked(int uid, long durationMillis) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003734 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003735 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
3736 }
3737
3738 public void noteVibratorOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003739 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003740 getUidStatsLocked(uid).noteVibratorOffLocked();
3741 }
3742
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003743 public void noteFlashlightOnLocked() {
3744 if (!mFlashlightOn) {
3745 final long elapsedRealtime = SystemClock.elapsedRealtime();
3746 final long uptime = SystemClock.uptimeMillis();
3747 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
3748 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
3749 + Integer.toHexString(mHistoryCur.states));
3750 addHistoryRecordLocked(elapsedRealtime, uptime);
3751 mFlashlightOn = true;
3752 mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
3753 }
3754 }
3755
3756 public void noteFlashlightOffLocked() {
3757 final long elapsedRealtime = SystemClock.elapsedRealtime();
3758 final long uptime = SystemClock.uptimeMillis();
3759 if (mFlashlightOn) {
3760 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
3761 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
3762 + Integer.toHexString(mHistoryCur.states));
3763 addHistoryRecordLocked(elapsedRealtime, uptime);
3764 mFlashlightOn = false;
3765 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
3766 }
3767 }
3768
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003769 public void noteWifiRadioPowerState(int powerState, long timestampNs) {
3770 final long elapsedRealtime = SystemClock.elapsedRealtime();
3771 final long uptime = SystemClock.uptimeMillis();
3772 if (mWifiRadioPowerState != powerState) {
3773 final boolean active =
3774 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
3775 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
3776 if (active) {
3777 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
3778 } else {
3779 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
3780 }
3781 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: "
3782 + Integer.toHexString(mHistoryCur.states));
3783 addHistoryRecordLocked(elapsedRealtime, uptime);
3784 mWifiRadioPowerState = powerState;
3785 }
3786 }
3787
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003788 public void noteWifiRunningLocked(WorkSource ws) {
3789 if (!mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003790 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003791 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003792 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003793 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
3794 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003795 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003796 mGlobalWifiRunning = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003797 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003798 int N = ws.size();
3799 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003800 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003801 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003802 }
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003803 scheduleSyncExternalStatsLocked("wifi-running");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003804 } else {
3805 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003806 }
3807 }
3808
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003809 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
3810 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003811 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003812 int N = oldWs.size();
3813 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003814 int uid = mapUid(oldWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003815 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003816 }
3817 N = newWs.size();
3818 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003819 int uid = mapUid(newWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003820 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003821 }
3822 } else {
3823 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
3824 }
3825 }
3826
3827 public void noteWifiStoppedLocked(WorkSource ws) {
3828 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003829 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003830 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003831 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003832 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
3833 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003834 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003835 mGlobalWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003836 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003837 int N = ws.size();
3838 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003839 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003840 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003841 }
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003842 scheduleSyncExternalStatsLocked("wifi-stopped");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003843 } else {
3844 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003845 }
3846 }
3847
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003848 public void noteWifiStateLocked(int wifiState, String accessPoint) {
3849 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
3850 if (mWifiState != wifiState) {
3851 final long elapsedRealtime = SystemClock.elapsedRealtime();
3852 if (mWifiState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003853 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003854 }
3855 mWifiState = wifiState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003856 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003857 scheduleSyncExternalStatsLocked("wifi-state");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003858 }
3859 }
3860
Dianne Hackborn3251b902014-06-20 14:40:53 -07003861 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
3862 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
3863 if (mWifiSupplState != supplState) {
3864 final long elapsedRealtime = SystemClock.elapsedRealtime();
3865 final long uptime = SystemClock.uptimeMillis();
3866 if (mWifiSupplState >= 0) {
3867 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime);
3868 }
3869 mWifiSupplState = supplState;
3870 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime);
3871 mHistoryCur.states2 =
3872 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
3873 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
3874 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
3875 + Integer.toHexString(mHistoryCur.states2));
3876 addHistoryRecordLocked(elapsedRealtime, uptime);
3877 }
3878 }
3879
3880 void stopAllWifiSignalStrengthTimersLocked(int except) {
3881 final long elapsedRealtime = SystemClock.elapsedRealtime();
3882 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
3883 if (i == except) {
3884 continue;
3885 }
3886 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) {
3887 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
3888 }
3889 }
3890 }
3891
3892 public void noteWifiRssiChangedLocked(int newRssi) {
3893 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
3894 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
3895 if (mWifiSignalStrengthBin != strengthBin) {
3896 final long elapsedRealtime = SystemClock.elapsedRealtime();
3897 final long uptime = SystemClock.uptimeMillis();
3898 if (mWifiSignalStrengthBin >= 0) {
3899 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked(
3900 elapsedRealtime);
3901 }
3902 if (strengthBin >= 0) {
3903 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
3904 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
3905 }
3906 mHistoryCur.states2 =
3907 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
3908 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
3909 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
3910 + Integer.toHexString(mHistoryCur.states2));
3911 addHistoryRecordLocked(elapsedRealtime, uptime);
3912 } else {
3913 stopAllWifiSignalStrengthTimersLocked(-1);
3914 }
3915 mWifiSignalStrengthBin = strengthBin;
3916 }
3917 }
3918
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003919 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003920
The Android Open Source Project10592532009-03-18 17:39:46 -07003921 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003922 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003923 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003924 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003925 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003926 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003927 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
3928 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003929 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003930 }
3931 mWifiFullLockNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003932 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003933 }
3934
3935 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003936 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003937 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003938 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003939 mWifiFullLockNesting--;
3940 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003941 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003942 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
3943 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003944 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003945 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003946 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003947 }
3948
Nick Pelly6ccaa542012-06-15 15:22:47 -07003949 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003950
Nick Pelly6ccaa542012-06-15 15:22:47 -07003951 public void noteWifiScanStartedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003952 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003953 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003954 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003955 if (mWifiScanNesting == 0) {
3956 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
3957 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003958 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003959 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003960 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003961 mWifiScanNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003962 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003963 }
3964
Nick Pelly6ccaa542012-06-15 15:22:47 -07003965 public void noteWifiScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003966 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003967 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003968 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003969 mWifiScanNesting--;
3970 if (mWifiScanNesting == 0) {
3971 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
3972 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003973 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003974 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003975 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003976 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003977 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003978
Robert Greenwalta029ea12013-09-25 16:38:12 -07003979 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003980 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003981 final long elapsedRealtime = SystemClock.elapsedRealtime();
3982 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003983 }
3984
3985 public void noteWifiBatchedScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003986 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003987 final long elapsedRealtime = SystemClock.elapsedRealtime();
3988 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003989 }
3990
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003991 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003992
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003993 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003994 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003995 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003996 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003997 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003998 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003999 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
4000 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004001 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004002 }
4003 mWifiMulticastNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004004 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004005 }
4006
4007 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004008 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004009 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07004010 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004011 mWifiMulticastNesting--;
4012 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004013 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004014 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
4015 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004016 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004017 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004018 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004019 }
4020
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004021 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
4022 int N = ws.size();
4023 for (int i=0; i<N; i++) {
4024 noteFullWifiLockAcquiredLocked(ws.get(i));
4025 }
4026 }
4027
4028 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
4029 int N = ws.size();
4030 for (int i=0; i<N; i++) {
4031 noteFullWifiLockReleasedLocked(ws.get(i));
4032 }
4033 }
4034
Nick Pelly6ccaa542012-06-15 15:22:47 -07004035 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004036 int N = ws.size();
4037 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004038 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004039 }
4040 }
4041
Nick Pelly6ccaa542012-06-15 15:22:47 -07004042 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004043 int N = ws.size();
4044 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004045 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004046 }
4047 }
4048
Robert Greenwalta029ea12013-09-25 16:38:12 -07004049 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
4050 int N = ws.size();
4051 for (int i=0; i<N; i++) {
4052 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
4053 }
4054 }
4055
4056 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
4057 int N = ws.size();
4058 for (int i=0; i<N; i++) {
4059 noteWifiBatchedScanStoppedLocked(ws.get(i));
4060 }
4061 }
4062
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004063 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
4064 int N = ws.size();
4065 for (int i=0; i<N; i++) {
4066 noteWifiMulticastEnabledLocked(ws.get(i));
4067 }
4068 }
4069
4070 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
4071 int N = ws.size();
4072 for (int i=0; i<N; i++) {
4073 noteWifiMulticastDisabledLocked(ws.get(i));
4074 }
4075 }
4076
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004077 private static String[] includeInStringArray(String[] array, String str) {
4078 if (ArrayUtils.indexOf(array, str) >= 0) {
4079 return array;
4080 }
4081 String[] newArray = new String[array.length+1];
4082 System.arraycopy(array, 0, newArray, 0, array.length);
4083 newArray[array.length] = str;
4084 return newArray;
4085 }
4086
4087 private static String[] excludeFromStringArray(String[] array, String str) {
4088 int index = ArrayUtils.indexOf(array, str);
4089 if (index >= 0) {
4090 String[] newArray = new String[array.length-1];
4091 if (index > 0) {
4092 System.arraycopy(array, 0, newArray, 0, index);
4093 }
4094 if (index < array.length-1) {
4095 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
4096 }
4097 return newArray;
4098 }
4099 return array;
4100 }
4101
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004102 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07004103 if (TextUtils.isEmpty(iface)) return;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004104 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004105 mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
4106 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004107 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004108 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
4109 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004110 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004111 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004112 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
4113 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004114 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004115 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
4116 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004117 }
4118 }
4119
4120 public void noteNetworkStatsEnabledLocked() {
4121 // During device boot, qtaguid isn't enabled until after the inital
4122 // loading of battery stats. Now that they're enabled, take our initial
4123 // snapshot for future delta calculation.
Adam Lesinskie08af192015-03-25 16:42:59 -07004124 final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
4125 updateMobileRadioStateLocked(elapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07004126 updateWifiStateLocked(null);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004127 }
4128
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004129 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
4130 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004131 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004132
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004133 @Override public int getScreenOnCount(int which) {
4134 return mScreenOnTimer.getCountLocked(which);
4135 }
4136
Dianne Hackborn617f8772009-03-31 15:04:46 -07004137 @Override public long getScreenBrightnessTime(int brightnessBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004138 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004139 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004140 elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004141 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004142
Jeff Browne95c3cd2014-05-02 16:59:26 -07004143 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
4144 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004145 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004146
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004147 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) {
4148 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004149 }
4150
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004151 @Override public int getPowerSaveModeEnabledCount(int which) {
4152 return mPowerSaveModeEnabledTimer.getCountLocked(which);
4153 }
4154
4155 @Override public long getDeviceIdleModeEnabledTime(long elapsedRealtimeUs, int which) {
4156 return mDeviceIdleModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4157 }
4158
4159 @Override public int getDeviceIdleModeEnabledCount(int which) {
4160 return mDeviceIdleModeEnabledTimer.getCountLocked(which);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004161 }
4162
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004163 @Override public long getDeviceIdlingTime(long elapsedRealtimeUs, int which) {
4164 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4165 }
4166
4167 @Override public int getDeviceIdlingCount(int which) {
4168 return mDeviceIdlingTimer.getCountLocked(which);
4169 }
4170
Dianne Hackborn1e01d162014-12-04 17:46:42 -08004171 @Override public int getNumConnectivityChange(int which) {
4172 int val = mNumConnectivityChange;
4173 if (which == STATS_CURRENT) {
4174 val -= mLoadedNumConnectivityChange;
4175 } else if (which == STATS_SINCE_UNPLUGGED) {
4176 val -= mUnpluggedNumConnectivityChange;
4177 }
4178 return val;
4179 }
4180
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004181 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
4182 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004183 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004184
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004185 @Override public int getPhoneOnCount(int which) {
4186 return mPhoneOnTimer.getCountLocked(which);
4187 }
4188
Dianne Hackborn627bba72009-03-24 22:32:56 -07004189 @Override public long getPhoneSignalStrengthTime(int strengthBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004190 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004191 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004192 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004193 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004194
4195 @Override public long getPhoneSignalScanningTime(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004196 long elapsedRealtimeUs, int which) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07004197 return mPhoneSignalScanningTimer.getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004198 elapsedRealtimeUs, which);
Amith Yamasanif37447b2009-10-08 18:28:01 -07004199 }
4200
Catherine Liufb900812012-07-17 14:12:56 -05004201 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
4202 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004203 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004204
Dianne Hackborn627bba72009-03-24 22:32:56 -07004205 @Override public long getPhoneDataConnectionTime(int dataType,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004206 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004207 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004208 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004209 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004210
Dianne Hackborn617f8772009-03-31 15:04:46 -07004211 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004212 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004213 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004214
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004215 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
4216 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004217 }
4218
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004219 @Override public int getMobileRadioActiveCount(int which) {
4220 return mMobileRadioActiveTimer.getCountLocked(which);
4221 }
4222
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004223 @Override public long getMobileRadioActiveAdjustedTime(int which) {
4224 return mMobileRadioActiveAdjustedTime.getCountLocked(which);
4225 }
4226
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004227 @Override public long getMobileRadioActiveUnknownTime(int which) {
4228 return mMobileRadioActiveUnknownTime.getCountLocked(which);
4229 }
4230
4231 @Override public int getMobileRadioActiveUnknownCount(int which) {
4232 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
4233 }
4234
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004235 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
4236 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004237 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004238
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004239 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
4240 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07004241 }
4242
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004243 @Override public long getWifiStateTime(int wifiState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004244 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004245 return mWifiStateTimer[wifiState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004246 elapsedRealtimeUs, which);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004247 }
4248
4249 @Override public int getWifiStateCount(int wifiState, int which) {
4250 return mWifiStateTimer[wifiState].getCountLocked(which);
4251 }
4252
Dianne Hackborn3251b902014-06-20 14:40:53 -07004253 @Override public long getWifiSupplStateTime(int state,
4254 long elapsedRealtimeUs, int which) {
4255 return mWifiSupplStateTimer[state].getTotalTimeLocked(
4256 elapsedRealtimeUs, which);
4257 }
4258
4259 @Override public int getWifiSupplStateCount(int state, int which) {
4260 return mWifiSupplStateTimer[state].getCountLocked(which);
4261 }
4262
4263 @Override public long getWifiSignalStrengthTime(int strengthBin,
4264 long elapsedRealtimeUs, int which) {
4265 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
4266 elapsedRealtimeUs, which);
4267 }
4268
4269 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) {
4270 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which);
4271 }
4272
Adam Lesinski17390762015-04-10 13:17:47 -07004273 @Override public boolean hasBluetoothActivityReporting() {
4274 return mHasBluetoothEnergyReporting;
4275 }
4276
Adam Lesinski33dac552015-03-09 15:24:48 -07004277 @Override public long getBluetoothControllerActivity(int type, int which) {
4278 if (type >= 0 && type < mBluetoothActivityCounters.length) {
4279 return mBluetoothActivityCounters[type].getCountLocked(which);
4280 }
4281 return 0;
4282 }
4283
Adam Lesinski17390762015-04-10 13:17:47 -07004284 @Override public boolean hasWifiActivityReporting() {
4285 return mHasWifiEnergyReporting;
4286 }
4287
Adam Lesinski33dac552015-03-09 15:24:48 -07004288 @Override public long getWifiControllerActivity(int type, int which) {
4289 if (type >= 0 && type < mWifiActivityCounters.length) {
4290 return mWifiActivityCounters[type].getCountLocked(which);
4291 }
4292 return 0;
4293 }
4294
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004295 @Override public long getFlashlightOnTime(long elapsedRealtimeUs, int which) {
4296 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4297 }
4298
4299 @Override public long getFlashlightOnCount(int which) {
4300 return mFlashlightOnTimer.getCountLocked(which);
4301 }
4302
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004303 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004304 public long getNetworkActivityBytes(int type, int which) {
4305 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
4306 return mNetworkByteActivityCounters[type].getCountLocked(which);
4307 } else {
4308 return 0;
4309 }
4310 }
4311
4312 @Override
4313 public long getNetworkActivityPackets(int type, int which) {
4314 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
4315 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004316 } else {
4317 return 0;
4318 }
4319 }
4320
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07004321 boolean isStartClockTimeValid() {
4322 return mStartClockTime > 365*24*60*60*1000L;
4323 }
4324
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08004325 @Override public long getStartClockTime() {
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07004326 if (!isStartClockTimeValid()) {
4327 // If the last clock time we got was very small, then we hadn't had a real
4328 // time yet, so try to get it again.
4329 mStartClockTime = System.currentTimeMillis();
4330 if (isStartClockTimeValid()) {
4331 recordCurrentTimeChangeLocked(mStartClockTime, SystemClock.elapsedRealtime(),
4332 SystemClock.uptimeMillis());
4333 }
4334 }
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08004335 return mStartClockTime;
4336 }
4337
Dianne Hackborncd0e3352014-08-07 17:08:09 -07004338 @Override public String getStartPlatformVersion() {
4339 return mStartPlatformVersion;
4340 }
4341
4342 @Override public String getEndPlatformVersion() {
4343 return mEndPlatformVersion;
4344 }
4345
4346 @Override public int getParcelVersion() {
4347 return VERSION;
4348 }
4349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004350 @Override public boolean getIsOnBattery() {
4351 return mOnBattery;
4352 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004354 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
4355 return mUidStats;
4356 }
4357
4358 /**
4359 * The statistics associated with a particular uid.
4360 */
4361 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004363 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004364
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004365 boolean mWifiRunning;
4366 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004367
The Android Open Source Project10592532009-03-18 17:39:46 -07004368 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07004369 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004370
Nick Pelly6ccaa542012-06-15 15:22:47 -07004371 boolean mWifiScanStarted;
4372 StopwatchTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004373
Dianne Hackborn61659e52014-07-09 16:13:01 -07004374 static final int NO_BATCHED_SCAN_STARTED = -1;
Robert Greenwalta029ea12013-09-25 16:38:12 -07004375 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4376 StopwatchTimer[] mWifiBatchedScanTimer;
4377
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004378 boolean mWifiMulticastEnabled;
4379 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004380
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004381 StopwatchTimer mAudioTurnedOnTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004382 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004383
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004384 StopwatchTimer mForegroundActivityTimer;
4385
Dianne Hackborn61659e52014-07-09 16:13:01 -07004386 static final int PROCESS_STATE_NONE = NUM_PROCESS_STATE;
4387 int mProcessState = PROCESS_STATE_NONE;
4388 StopwatchTimer[] mProcessStateTimer;
4389
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004390 BatchTimer mVibratorOnTimer;
4391
Dianne Hackborn617f8772009-03-31 15:04:46 -07004392 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004393
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004394 LongSamplingCounter[] mNetworkByteActivityCounters;
4395 LongSamplingCounter[] mNetworkPacketActivityCounters;
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004396 LongSamplingCounter mMobileRadioActiveTime;
4397 LongSamplingCounter mMobileRadioActiveCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 /**
Adam Lesinskie08af192015-03-25 16:42:59 -07004400 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode.
4401 */
4402 LongSamplingCounter[] mWifiControllerTime =
4403 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
4404
4405 /**
4406 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode.
4407 */
4408 LongSamplingCounter[] mBluetoothControllerTime =
4409 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
4410
4411 /**
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08004412 * The CPU times we had at the last history details update.
4413 */
4414 long mLastStepUserTime;
4415 long mLastStepSystemTime;
4416 long mCurStepUserTime;
4417 long mCurStepSystemTime;
4418
4419 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 * The statistics we have collected for this uid's wake locks.
4421 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004422 final OverflowArrayMap<Wakelock> mWakelockStats = new OverflowArrayMap<Wakelock>() {
4423 @Override public Wakelock instantiateObject() { return new Wakelock(); }
4424 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004425
4426 /**
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004427 * The statistics we have collected for this uid's syncs.
4428 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004429 final OverflowArrayMap<StopwatchTimer> mSyncStats = new OverflowArrayMap<StopwatchTimer>() {
4430 @Override public StopwatchTimer instantiateObject() {
4431 return new StopwatchTimer(Uid.this, SYNC, null, mOnBatteryTimeBase);
4432 }
4433 };
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004434
4435 /**
4436 * The statistics we have collected for this uid's jobs.
4437 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004438 final OverflowArrayMap<StopwatchTimer> mJobStats = new OverflowArrayMap<StopwatchTimer>() {
4439 @Override public StopwatchTimer instantiateObject() {
4440 return new StopwatchTimer(Uid.this, JOB, null, mOnBatteryTimeBase);
4441 }
4442 };
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004443
4444 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004445 * The statistics we have collected for this uid's sensor activations.
4446 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004447 final SparseArray<Sensor> mSensorStats = new SparseArray<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004448
4449 /**
4450 * The statistics we have collected for this uid's processes.
4451 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004452 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453
4454 /**
4455 * The statistics we have collected for this uid's processes.
4456 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004457 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004458
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004459 /**
4460 * The transient wake stats we have collected for this uid's pids.
4461 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004462 final SparseArray<Pid> mPids = new SparseArray<>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004464 public Uid(int uid) {
4465 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004466 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004467 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004468 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004469 mFullWifiLockTimers, mOnBatteryTimeBase);
Nick Pelly6ccaa542012-06-15 15:22:47 -07004470 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004471 mWifiScanTimers, mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004472 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004473 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004474 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn61659e52014-07-09 16:13:01 -07004475 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 }
4477
4478 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004479 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004480 return mWakelockStats.getMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 }
4482
4483 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004484 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004485 return mSyncStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004486 }
4487
4488 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004489 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004490 return mJobStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004491 }
4492
4493 @Override
Dianne Hackborn61659e52014-07-09 16:13:01 -07004494 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 return mSensorStats;
4496 }
4497
4498 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004499 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004500 return mProcessStats;
4501 }
4502
4503 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004504 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004505 return mPackageStats;
4506 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004507
4508 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 public int getUid() {
4510 return mUid;
4511 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004512
4513 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004514 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004515 if (!mWifiRunning) {
4516 mWifiRunning = true;
4517 if (mWifiRunningTimer == null) {
4518 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004519 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004520 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004521 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004522 }
4523 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004524
Dianne Hackborn617f8772009-03-31 15:04:46 -07004525 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004526 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004527 if (mWifiRunning) {
4528 mWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004529 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004530 }
4531 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004532
Dianne Hackborn617f8772009-03-31 15:04:46 -07004533 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004534 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07004535 if (!mFullWifiLockOut) {
4536 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004537 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004538 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004539 mFullWifiLockTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004540 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004541 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004542 }
4543 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004544
The Android Open Source Project10592532009-03-18 17:39:46 -07004545 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004546 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07004547 if (mFullWifiLockOut) {
4548 mFullWifiLockOut = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004549 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004550 }
4551 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004552
The Android Open Source Project10592532009-03-18 17:39:46 -07004553 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004554 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004555 if (!mWifiScanStarted) {
4556 mWifiScanStarted = true;
4557 if (mWifiScanTimer == null) {
4558 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004559 mWifiScanTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004560 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004561 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004562 }
4563 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004564
The Android Open Source Project10592532009-03-18 17:39:46 -07004565 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004566 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004567 if (mWifiScanStarted) {
4568 mWifiScanStarted = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004569 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004570 }
4571 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004572
4573 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004574 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004575 int bin = 0;
4576 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
4577 csph = csph >> 3;
4578 bin++;
4579 }
4580
4581 if (mWifiBatchedScanBinStarted == bin) return;
4582
4583 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
4584 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004585 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004586 }
4587 mWifiBatchedScanBinStarted = bin;
4588 if (mWifiBatchedScanTimer[bin] == null) {
4589 makeWifiBatchedScanBin(bin, null);
4590 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004591 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004592 }
4593
4594 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004595 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004596 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
4597 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004598 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004599 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4600 }
4601 }
4602
4603 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004604 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004605 if (!mWifiMulticastEnabled) {
4606 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004607 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004608 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004609 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004610 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004611 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004612 }
4613 }
4614
4615 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004616 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004617 if (mWifiMulticastEnabled) {
4618 mWifiMulticastEnabled = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004619 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004620 }
4621 }
4622
Adam Lesinskie08af192015-03-25 16:42:59 -07004623 public void noteWifiControllerActivityLocked(int type, long timeMs) {
4624 if (mWifiControllerTime[type] == null) {
4625 mWifiControllerTime[type] = new LongSamplingCounter(mOnBatteryTimeBase);
4626 }
4627 mWifiControllerTime[type].addCountLocked(timeMs);
4628 }
4629
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004630 public StopwatchTimer createAudioTurnedOnTimerLocked() {
4631 if (mAudioTurnedOnTimer == null) {
4632 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004633 mAudioTurnedOnTimers, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004634 }
4635 return mAudioTurnedOnTimer;
4636 }
4637
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004638 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004639 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4640 }
4641
4642 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
4643 if (mAudioTurnedOnTimer != null) {
4644 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004645 }
4646 }
4647
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004648 public void noteResetAudioLocked(long elapsedRealtimeMs) {
4649 if (mAudioTurnedOnTimer != null) {
4650 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004651 }
4652 }
4653
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004654 public StopwatchTimer createVideoTurnedOnTimerLocked() {
4655 if (mVideoTurnedOnTimer == null) {
4656 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004657 mVideoTurnedOnTimers, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004658 }
4659 return mVideoTurnedOnTimer;
4660 }
4661
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004662 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004663 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4664 }
4665
4666 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
4667 if (mVideoTurnedOnTimer != null) {
4668 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004669 }
4670 }
4671
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004672 public void noteResetVideoLocked(long elapsedRealtimeMs) {
4673 if (mVideoTurnedOnTimer != null) {
4674 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004675 }
4676 }
4677
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004678 public StopwatchTimer createForegroundActivityTimerLocked() {
4679 if (mForegroundActivityTimer == null) {
4680 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004681 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004682 }
4683 return mForegroundActivityTimer;
4684 }
4685
4686 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004687 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004688 // We always start, since we want multiple foreground PIDs to nest
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004689 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004690 }
4691
4692 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004693 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004694 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004695 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004696 }
4697 }
4698
Dianne Hackborn61659e52014-07-09 16:13:01 -07004699 void updateUidProcessStateLocked(int state, long elapsedRealtimeMs) {
4700 if (mProcessState == state) return;
4701
4702 if (mProcessState != PROCESS_STATE_NONE) {
4703 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs);
4704 }
4705 mProcessState = state;
4706 if (state != PROCESS_STATE_NONE) {
4707 if (mProcessStateTimer[state] == null) {
4708 makeProcessState(state, null);
4709 }
4710 mProcessStateTimer[state].startRunningLocked(elapsedRealtimeMs);
4711 }
4712 }
4713
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004714 public BatchTimer createVibratorOnTimerLocked() {
4715 if (mVibratorOnTimer == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004716 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004717 }
4718 return mVibratorOnTimer;
4719 }
4720
4721 public void noteVibratorOnLocked(long durationMillis) {
4722 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
4723 }
4724
4725 public void noteVibratorOffLocked() {
4726 if (mVibratorOnTimer != null) {
4727 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004728 }
4729 }
4730
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004731 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004732 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004733 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004734 return 0;
4735 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004736 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004737 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004738
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004739 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004740 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004741 if (mFullWifiLockTimer == null) {
4742 return 0;
4743 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004744 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004745 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004746
4747 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004748 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004749 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004750 return 0;
4751 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004752 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004753 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004754
4755 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07004756 public int getWifiScanCount(int which) {
4757 if (mWifiScanTimer == null) {
4758 return 0;
4759 }
4760 return mWifiScanTimer.getCountLocked(which);
4761 }
4762
4763 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004764 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004765 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
4766 if (mWifiBatchedScanTimer[csphBin] == null) {
4767 return 0;
4768 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004769 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004770 }
4771
4772 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07004773 public int getWifiBatchedScanCount(int csphBin, int which) {
4774 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
4775 if (mWifiBatchedScanTimer[csphBin] == null) {
4776 return 0;
4777 }
4778 return mWifiBatchedScanTimer[csphBin].getCountLocked(which);
4779 }
4780
4781 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004782 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004783 if (mWifiMulticastTimer == null) {
4784 return 0;
4785 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004786 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004787 }
4788
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004789 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004790 public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004791 if (mAudioTurnedOnTimer == null) {
4792 return 0;
4793 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004794 return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004795 }
4796
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004797 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004798 public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004799 if (mVideoTurnedOnTimer == null) {
4800 return 0;
4801 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004802 return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004803 }
4804
Dianne Hackborn617f8772009-03-31 15:04:46 -07004805 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004806 public Timer getForegroundActivityTimer() {
4807 return mForegroundActivityTimer;
4808 }
4809
Dianne Hackborn61659e52014-07-09 16:13:01 -07004810 void makeProcessState(int i, Parcel in) {
4811 if (i < 0 || i >= NUM_PROCESS_STATE) return;
4812
4813 if (in == null) {
4814 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null,
4815 mOnBatteryTimeBase);
4816 } else {
4817 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null,
4818 mOnBatteryTimeBase, in);
4819 }
4820 }
4821
4822 @Override
4823 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) {
4824 if (state < 0 || state >= NUM_PROCESS_STATE) return 0;
4825 if (mProcessStateTimer[state] == null) {
4826 return 0;
4827 }
4828 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which);
4829 }
4830
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004831 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004832 public Timer getVibratorOnTimer() {
4833 return mVibratorOnTimer;
4834 }
4835
4836 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07004837 public void noteUserActivityLocked(int type) {
4838 if (mUserActivityCounters == null) {
4839 initUserActivityLocked();
4840 }
Jeff Browndf693de2012-07-27 12:03:38 -07004841 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
4842 mUserActivityCounters[type].stepAtomic();
4843 } else {
4844 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
4845 new Throwable());
4846 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07004847 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004848
Dianne Hackborn617f8772009-03-31 15:04:46 -07004849 @Override
4850 public boolean hasUserActivity() {
4851 return mUserActivityCounters != null;
4852 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004853
Dianne Hackborn617f8772009-03-31 15:04:46 -07004854 @Override
4855 public int getUserActivityCount(int type, int which) {
4856 if (mUserActivityCounters == null) {
4857 return 0;
4858 }
Evan Millarc64edde2009-04-18 12:26:32 -07004859 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004860 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004861
Robert Greenwalta029ea12013-09-25 16:38:12 -07004862 void makeWifiBatchedScanBin(int i, Parcel in) {
4863 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
4864
4865 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i);
4866 if (collected == null) {
4867 collected = new ArrayList<StopwatchTimer>();
4868 mWifiBatchedScanTimers.put(i, collected);
4869 }
4870 if (in == null) {
4871 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004872 mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004873 } else {
4874 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004875 mOnBatteryTimeBase, in);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004876 }
4877 }
4878
4879
Dianne Hackborn617f8772009-03-31 15:04:46 -07004880 void initUserActivityLocked() {
4881 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
4882 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004883 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004884 }
4885 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004886
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004887 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
4888 if (mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004889 initNetworkActivityLocked();
4890 }
4891 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004892 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
4893 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004894 } else {
4895 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
4896 new Throwable());
4897 }
4898 }
4899
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004900 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
4901 if (mNetworkByteActivityCounters == null) {
4902 initNetworkActivityLocked();
4903 }
4904 mMobileRadioActiveTime.addCountLocked(batteryUptime);
4905 mMobileRadioActiveCount.addCountLocked(1);
4906 }
4907
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004908 @Override
4909 public boolean hasNetworkActivity() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004910 return mNetworkByteActivityCounters != null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004911 }
4912
4913 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004914 public long getNetworkActivityBytes(int type, int which) {
4915 if (mNetworkByteActivityCounters != null && type >= 0
4916 && type < mNetworkByteActivityCounters.length) {
4917 return mNetworkByteActivityCounters[type].getCountLocked(which);
4918 } else {
4919 return 0;
4920 }
4921 }
4922
4923 @Override
4924 public long getNetworkActivityPackets(int type, int which) {
4925 if (mNetworkPacketActivityCounters != null && type >= 0
4926 && type < mNetworkPacketActivityCounters.length) {
4927 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004928 } else {
4929 return 0;
4930 }
4931 }
4932
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004933 @Override
4934 public long getMobileRadioActiveTime(int which) {
4935 return mMobileRadioActiveTime != null
4936 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
4937 }
4938
4939 @Override
4940 public int getMobileRadioActiveCount(int which) {
4941 return mMobileRadioActiveCount != null
4942 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
4943 }
4944
Adam Lesinskie08af192015-03-25 16:42:59 -07004945 @Override
4946 public long getWifiControllerActivity(int type, int which) {
4947 if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES &&
4948 mWifiControllerTime[type] != null) {
4949 return mWifiControllerTime[type].getCountLocked(which);
4950 }
4951 return 0;
4952 }
4953
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004954 void initNetworkActivityLocked() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004955 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
4956 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004957 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004958 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
4959 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004960 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004961 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase);
4962 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004964
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004965 /**
4966 * Clear all stats for this uid. Returns true if the uid is completely
4967 * inactive so can be dropped.
4968 */
4969 boolean reset() {
4970 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004971
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004972 if (mWifiRunningTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004973 active |= !mWifiRunningTimer.reset(false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004974 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004975 }
4976 if (mFullWifiLockTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004977 active |= !mFullWifiLockTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004978 active |= mFullWifiLockOut;
4979 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004980 if (mWifiScanTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004981 active |= !mWifiScanTimer.reset(false);
Nick Pelly6ccaa542012-06-15 15:22:47 -07004982 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004983 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004984 if (mWifiBatchedScanTimer != null) {
4985 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4986 if (mWifiBatchedScanTimer[i] != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004987 active |= !mWifiBatchedScanTimer[i].reset(false);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004988 }
4989 }
4990 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
4991 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004992 if (mWifiMulticastTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004993 active |= !mWifiMulticastTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004994 active |= mWifiMulticastEnabled;
4995 }
4996 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004997 active |= !mAudioTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004998 }
4999 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005000 active |= !mVideoTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005001 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005002 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005003 active |= !mForegroundActivityTimer.reset(false);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005004 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005005 if (mProcessStateTimer != null) {
5006 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5007 if (mProcessStateTimer[i] != null) {
5008 active |= !mProcessStateTimer[i].reset(false);
5009 }
5010 }
5011 active |= (mProcessState != PROCESS_STATE_NONE);
5012 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005013 if (mVibratorOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005014 if (mVibratorOnTimer.reset(false)) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005015 mVibratorOnTimer.detach();
5016 mVibratorOnTimer = null;
5017 } else {
5018 active = true;
5019 }
5020 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005021
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005022 if (mUserActivityCounters != null) {
5023 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5024 mUserActivityCounters[i].reset(false);
5025 }
5026 }
5027
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005028 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005029 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005030 mNetworkByteActivityCounters[i].reset(false);
5031 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005032 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005033 mMobileRadioActiveTime.reset(false);
5034 mMobileRadioActiveCount.reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005035 }
5036
Adam Lesinskie08af192015-03-25 16:42:59 -07005037 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5038 if (mWifiControllerTime[i] != null) {
5039 mWifiControllerTime[i].reset(false);
5040 }
5041
5042 if (mBluetoothControllerTime[i] != null) {
5043 mBluetoothControllerTime[i].reset(false);
5044 }
5045 }
5046
Dianne Hackbornd953c532014-08-16 18:17:38 -07005047 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
5048 for (int iw=wakeStats.size()-1; iw>=0; iw--) {
5049 Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005050 if (wl.reset()) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005051 wakeStats.removeAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005052 } else {
5053 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005054 }
5055 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005056 mWakelockStats.cleanup();
5057 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap();
5058 for (int is=syncStats.size()-1; is>=0; is--) {
5059 StopwatchTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005060 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005061 syncStats.removeAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005062 timer.detach();
5063 } else {
5064 active = true;
5065 }
5066 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005067 mSyncStats.cleanup();
5068 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
5069 for (int ij=jobStats.size()-1; ij>=0; ij--) {
5070 StopwatchTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005071 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005072 jobStats.removeAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005073 timer.detach();
5074 } else {
5075 active = true;
5076 }
5077 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005078 mJobStats.cleanup();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005079 for (int ise=mSensorStats.size()-1; ise>=0; ise--) {
5080 Sensor s = mSensorStats.valueAt(ise);
5081 if (s.reset()) {
5082 mSensorStats.removeAt(ise);
5083 } else {
5084 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005085 }
5086 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005087 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
5088 Proc proc = mProcessStats.valueAt(ip);
5089 if (proc.mProcessState == PROCESS_STATE_NONE) {
5090 proc.detach();
5091 mProcessStats.removeAt(ip);
5092 } else {
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005093 proc.reset();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005094 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005095 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005096 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005097 if (mPids.size() > 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005098 for (int i=mPids.size()-1; i>=0; i--) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005099 Pid pid = mPids.valueAt(i);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005100 if (pid.mWakeNesting > 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005101 active = true;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005102 } else {
5103 mPids.removeAt(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005104 }
5105 }
5106 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005107 if (mPackageStats.size() > 0) {
5108 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
5109 while (it.hasNext()) {
5110 Map.Entry<String, Pkg> pkgEntry = it.next();
5111 Pkg p = pkgEntry.getValue();
5112 p.detach();
5113 if (p.mServiceStats.size() > 0) {
5114 Iterator<Map.Entry<String, Pkg.Serv>> it2
5115 = p.mServiceStats.entrySet().iterator();
5116 while (it2.hasNext()) {
5117 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
5118 servEntry.getValue().detach();
5119 }
5120 }
5121 }
5122 mPackageStats.clear();
5123 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005124
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005125 mLastStepUserTime = mLastStepSystemTime = 0;
5126 mCurStepUserTime = mCurStepSystemTime = 0;
5127
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005128 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005129 if (mWifiRunningTimer != null) {
5130 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005131 }
5132 if (mFullWifiLockTimer != null) {
5133 mFullWifiLockTimer.detach();
5134 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005135 if (mWifiScanTimer != null) {
5136 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005137 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005138 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5139 if (mWifiBatchedScanTimer[i] != null) {
5140 mWifiBatchedScanTimer[i].detach();
5141 }
5142 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005143 if (mWifiMulticastTimer != null) {
5144 mWifiMulticastTimer.detach();
5145 }
5146 if (mAudioTurnedOnTimer != null) {
5147 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005148 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005149 }
5150 if (mVideoTurnedOnTimer != null) {
5151 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005152 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005153 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005154 if (mForegroundActivityTimer != null) {
5155 mForegroundActivityTimer.detach();
5156 mForegroundActivityTimer = null;
5157 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005158 if (mUserActivityCounters != null) {
5159 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5160 mUserActivityCounters[i].detach();
5161 }
5162 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005163 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005164 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005165 mNetworkByteActivityCounters[i].detach();
5166 mNetworkPacketActivityCounters[i].detach();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005167 }
5168 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005169
5170 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5171 if (mWifiControllerTime[i] != null) {
5172 mWifiControllerTime[i].detach();
5173 }
5174
5175 if (mBluetoothControllerTime[i] != null) {
5176 mBluetoothControllerTime[i].detach();
5177 }
5178 }
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005179 mPids.clear();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005180 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005181
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005182 return !active;
5183 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005184
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005185 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005186 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
5187 int NW = wakeStats.size();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005188 out.writeInt(NW);
5189 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005190 out.writeString(wakeStats.keyAt(iw));
5191 Uid.Wakelock wakelock = wakeStats.valueAt(iw);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005192 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005193 }
5194
Dianne Hackbornd953c532014-08-16 18:17:38 -07005195 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap();
5196 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005197 out.writeInt(NS);
5198 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005199 out.writeString(syncStats.keyAt(is));
5200 StopwatchTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005201 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
5202 }
5203
Dianne Hackbornd953c532014-08-16 18:17:38 -07005204 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
5205 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005206 out.writeInt(NJ);
5207 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005208 out.writeString(jobStats.keyAt(ij));
5209 StopwatchTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005210 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
5211 }
5212
Dianne Hackborn61659e52014-07-09 16:13:01 -07005213 int NSE = mSensorStats.size();
5214 out.writeInt(NSE);
5215 for (int ise=0; ise<NSE; ise++) {
5216 out.writeInt(mSensorStats.keyAt(ise));
5217 Uid.Sensor sensor = mSensorStats.valueAt(ise);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005218 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 }
5220
Dianne Hackborn61659e52014-07-09 16:13:01 -07005221 int NP = mProcessStats.size();
5222 out.writeInt(NP);
5223 for (int ip=0; ip<NP; ip++) {
5224 out.writeString(mProcessStats.keyAt(ip));
5225 Uid.Proc proc = mProcessStats.valueAt(ip);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226 proc.writeToParcelLocked(out);
5227 }
5228
5229 out.writeInt(mPackageStats.size());
5230 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
5231 out.writeString(pkgEntry.getKey());
5232 Uid.Pkg pkg = pkgEntry.getValue();
5233 pkg.writeToParcelLocked(out);
5234 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005235
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005236 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005237 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005238 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005239 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005240 out.writeInt(0);
5241 }
5242 if (mFullWifiLockTimer != null) {
5243 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005244 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005245 } else {
5246 out.writeInt(0);
5247 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005248 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005249 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005250 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005251 } else {
5252 out.writeInt(0);
5253 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005254 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5255 if (mWifiBatchedScanTimer[i] != null) {
5256 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005257 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005258 } else {
5259 out.writeInt(0);
5260 }
5261 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005262 if (mWifiMulticastTimer != null) {
5263 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005264 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005265 } else {
5266 out.writeInt(0);
5267 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005268
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005269 if (mAudioTurnedOnTimer != null) {
5270 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005271 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005272 } else {
5273 out.writeInt(0);
5274 }
5275 if (mVideoTurnedOnTimer != null) {
5276 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005277 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005278 } else {
5279 out.writeInt(0);
5280 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005281 if (mForegroundActivityTimer != null) {
5282 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005283 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005284 } else {
5285 out.writeInt(0);
5286 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005287 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5288 if (mProcessStateTimer[i] != null) {
5289 out.writeInt(1);
5290 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs);
5291 } else {
5292 out.writeInt(0);
5293 }
5294 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005295 if (mVibratorOnTimer != null) {
5296 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005297 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005298 } else {
5299 out.writeInt(0);
5300 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005301 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07005302 out.writeInt(1);
5303 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5304 mUserActivityCounters[i].writeToParcel(out);
5305 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005306 } else {
5307 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005308 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005309 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005310 out.writeInt(1);
5311 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005312 mNetworkByteActivityCounters[i].writeToParcel(out);
5313 mNetworkPacketActivityCounters[i].writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005314 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005315 mMobileRadioActiveTime.writeToParcel(out);
5316 mMobileRadioActiveCount.writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005317 } else {
5318 out.writeInt(0);
5319 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005320
5321 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5322 if (mWifiControllerTime[i] != null) {
5323 out.writeInt(1);
5324 mWifiControllerTime[i].writeToParcel(out);
5325 } else {
5326 out.writeInt(0);
5327 }
5328 }
5329
5330 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5331 if (mBluetoothControllerTime[i] != null) {
5332 out.writeInt(1);
5333 mBluetoothControllerTime[i].writeToParcel(out);
5334 } else {
5335 out.writeInt(0);
5336 }
5337 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005338 }
5339
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005340 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005341 int numWakelocks = in.readInt();
5342 mWakelockStats.clear();
5343 for (int j = 0; j < numWakelocks; j++) {
5344 String wakelockName = in.readString();
5345 Uid.Wakelock wakelock = new Wakelock();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005346 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
Dianne Hackbornd953c532014-08-16 18:17:38 -07005347 mWakelockStats.add(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005348 }
5349
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005350 int numSyncs = in.readInt();
5351 mSyncStats.clear();
5352 for (int j = 0; j < numSyncs; j++) {
5353 String syncName = in.readString();
5354 if (in.readInt() != 0) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005355 mSyncStats.add(syncName,
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005356 new StopwatchTimer(Uid.this, SYNC, null, timeBase, in));
5357 }
5358 }
5359
5360 int numJobs = in.readInt();
5361 mJobStats.clear();
5362 for (int j = 0; j < numJobs; j++) {
5363 String jobName = in.readString();
5364 if (in.readInt() != 0) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005365 mJobStats.add(jobName, new StopwatchTimer(Uid.this, JOB, null, timeBase, in));
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005366 }
5367 }
5368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005369 int numSensors = in.readInt();
5370 mSensorStats.clear();
5371 for (int k = 0; k < numSensors; k++) {
5372 int sensorNumber = in.readInt();
5373 Uid.Sensor sensor = new Sensor(sensorNumber);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005374 sensor.readFromParcelLocked(mOnBatteryTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005375 mSensorStats.put(sensorNumber, sensor);
5376 }
5377
5378 int numProcs = in.readInt();
5379 mProcessStats.clear();
5380 for (int k = 0; k < numProcs; k++) {
5381 String processName = in.readString();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005382 Uid.Proc proc = new Proc(processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005383 proc.readFromParcelLocked(in);
5384 mProcessStats.put(processName, proc);
5385 }
5386
5387 int numPkgs = in.readInt();
5388 mPackageStats.clear();
5389 for (int l = 0; l < numPkgs; l++) {
5390 String packageName = in.readString();
5391 Uid.Pkg pkg = new Pkg();
5392 pkg.readFromParcelLocked(in);
5393 mPackageStats.put(packageName, pkg);
5394 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005395
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005396 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005397 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005398 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005399 mWifiRunningTimers, mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005400 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005401 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005402 }
5403 mFullWifiLockOut = false;
5404 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005405 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005406 mFullWifiLockTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005407 } else {
5408 mFullWifiLockTimer = null;
5409 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005410 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005411 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005412 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005413 mWifiScanTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005414 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005415 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005416 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005417 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
5418 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5419 if (in.readInt() != 0) {
5420 makeWifiBatchedScanBin(i, in);
5421 } else {
5422 mWifiBatchedScanTimer[i] = null;
5423 }
5424 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005425 mWifiMulticastEnabled = false;
5426 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005427 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005428 mWifiMulticastTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005429 } else {
5430 mWifiMulticastTimer = null;
5431 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005432 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005433 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07005434 mAudioTurnedOnTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005435 } else {
5436 mAudioTurnedOnTimer = null;
5437 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005438 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005439 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07005440 mVideoTurnedOnTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005441 } else {
5442 mVideoTurnedOnTimer = null;
5443 }
5444 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005445 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005446 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005447 } else {
5448 mForegroundActivityTimer = null;
5449 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005450 mProcessState = PROCESS_STATE_NONE;
5451 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5452 if (in.readInt() != 0) {
5453 makeProcessState(i, in);
5454 } else {
5455 mProcessStateTimer[i] = null;
5456 }
5457 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005458 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005459 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005460 } else {
5461 mVibratorOnTimer = null;
5462 }
5463 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07005464 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
5465 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005466 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005467 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005468 } else {
5469 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07005470 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005471 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005472 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
5473 mNetworkPacketActivityCounters
5474 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005475 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005476 mNetworkByteActivityCounters[i]
5477 = new LongSamplingCounter(mOnBatteryTimeBase, in);
5478 mNetworkPacketActivityCounters[i]
5479 = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005480 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005481 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
5482 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005483 } else {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005484 mNetworkByteActivityCounters = null;
5485 mNetworkPacketActivityCounters = null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005486 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005487
5488 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5489 if (in.readInt() != 0) {
5490 mWifiControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
5491 } else {
5492 mWifiControllerTime[i] = null;
5493 }
5494 }
5495
5496 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5497 if (in.readInt() != 0) {
5498 mBluetoothControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
5499 } else {
5500 mBluetoothControllerTime[i] = null;
5501 }
5502 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005503 }
5504
5505 /**
5506 * The statistics associated with a particular wake lock.
5507 */
5508 public final class Wakelock extends BatteryStats.Uid.Wakelock {
5509 /**
5510 * How long (in ms) this uid has been keeping the device partially awake.
5511 */
Evan Millarc64edde2009-04-18 12:26:32 -07005512 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005513
5514 /**
5515 * How long (in ms) this uid has been keeping the device fully awake.
5516 */
Evan Millarc64edde2009-04-18 12:26:32 -07005517 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518
5519 /**
5520 * How long (in ms) this uid has had a window keeping the device awake.
5521 */
Evan Millarc64edde2009-04-18 12:26:32 -07005522 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005523
5524 /**
5525 * Reads a possibly null Timer from a Parcel. The timer is associated with the
5526 * proper timer pool from the given BatteryStatsImpl object.
5527 *
5528 * @param in the Parcel to be read from.
5529 * return a new Timer, or null.
5530 */
Evan Millarc64edde2009-04-18 12:26:32 -07005531 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005532 TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 if (in.readInt() == 0) {
5534 return null;
5535 }
5536
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005537 return new StopwatchTimer(Uid.this, type, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005538 }
5539
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005540 boolean reset() {
5541 boolean wlactive = false;
5542 if (mTimerFull != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005543 wlactive |= !mTimerFull.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005544 }
5545 if (mTimerPartial != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005546 wlactive |= !mTimerPartial.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005547 }
5548 if (mTimerWindow != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005549 wlactive |= !mTimerWindow.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005550 }
5551 if (!wlactive) {
5552 if (mTimerFull != null) {
5553 mTimerFull.detach();
5554 mTimerFull = null;
5555 }
5556 if (mTimerPartial != null) {
5557 mTimerPartial.detach();
5558 mTimerPartial = null;
5559 }
5560 if (mTimerWindow != null) {
5561 mTimerWindow.detach();
5562 mTimerWindow = null;
5563 }
5564 }
5565 return !wlactive;
5566 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005567
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005568 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005570 mPartialTimers, screenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005571 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005572 mFullTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005573 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005574 mWindowTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005575 }
5576
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005577 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
5578 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
5579 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
5580 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005581 }
5582
5583 @Override
5584 public Timer getWakeTime(int type) {
5585 switch (type) {
5586 case WAKE_TYPE_FULL: return mTimerFull;
5587 case WAKE_TYPE_PARTIAL: return mTimerPartial;
5588 case WAKE_TYPE_WINDOW: return mTimerWindow;
5589 default: throw new IllegalArgumentException("type = " + type);
5590 }
5591 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005592
5593 public StopwatchTimer getStopwatchTimer(int type) {
5594 StopwatchTimer t;
5595 switch (type) {
5596 case WAKE_TYPE_PARTIAL:
5597 t = mTimerPartial;
5598 if (t == null) {
5599 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
5600 mPartialTimers, mOnBatteryScreenOffTimeBase);
5601 mTimerPartial = t;
5602 }
5603 return t;
5604 case WAKE_TYPE_FULL:
5605 t = mTimerFull;
5606 if (t == null) {
5607 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
5608 mFullTimers, mOnBatteryTimeBase);
5609 mTimerFull = t;
5610 }
5611 return t;
5612 case WAKE_TYPE_WINDOW:
5613 t = mTimerWindow;
5614 if (t == null) {
5615 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
5616 mWindowTimers, mOnBatteryTimeBase);
5617 mTimerWindow = t;
5618 }
5619 return t;
5620 default:
5621 throw new IllegalArgumentException("type=" + type);
5622 }
5623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005624 }
5625
5626 public final class Sensor extends BatteryStats.Uid.Sensor {
5627 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07005628 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005630 public Sensor(int handle) {
5631 mHandle = handle;
5632 }
5633
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005634 private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005635 if (in.readInt() == 0) {
5636 return null;
5637 }
5638
Evan Millarc64edde2009-04-18 12:26:32 -07005639 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005640 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07005641 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005642 mSensorTimers.put(mHandle, pool);
5643 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005644 return new StopwatchTimer(Uid.this, 0, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005645 }
5646
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005647 boolean reset() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005648 if (mTimer.reset(true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005649 mTimer = null;
5650 return true;
5651 }
5652 return false;
5653 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005654
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005655 void readFromParcelLocked(TimeBase timeBase, Parcel in) {
5656 mTimer = readTimerFromParcel(timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005657 }
5658
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005659 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
5660 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005661 }
5662
5663 @Override
5664 public Timer getSensorTime() {
5665 return mTimer;
5666 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005667
5668 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005669 public int getHandle() {
5670 return mHandle;
5671 }
5672 }
5673
5674 /**
5675 * The statistics associated with a particular process.
5676 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005677 public final class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005678 /**
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005679 * The name of this process.
5680 */
5681 final String mName;
5682
5683 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -08005684 * Remains true until removed from the stats.
5685 */
5686 boolean mActive = true;
5687
5688 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005689 * Total time (in ms) spent executing in user code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005690 */
5691 long mUserTime;
5692
5693 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005694 * Total time (in ms) spent executing in kernel code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005695 */
5696 long mSystemTime;
5697
5698 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005699 * Amount of time (in ms) the process was running in the foreground.
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005700 */
5701 long mForegroundTime;
5702
5703 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005704 * Number of times the process has been started.
5705 */
5706 int mStarts;
5707
5708 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005709 * Number of times the process has crashed.
5710 */
5711 int mNumCrashes;
5712
5713 /**
5714 * Number of times the process has had an ANR.
5715 */
5716 int mNumAnrs;
5717
5718 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005719 * The amount of user time loaded from a previous save.
5720 */
5721 long mLoadedUserTime;
5722
5723 /**
5724 * The amount of system time loaded from a previous save.
5725 */
5726 long mLoadedSystemTime;
5727
5728 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005729 * The amount of foreground time loaded from a previous save.
5730 */
5731 long mLoadedForegroundTime;
5732
5733 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005734 * The number of times the process has started from a previous save.
5735 */
5736 int mLoadedStarts;
5737
5738 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005739 * Number of times the process has crashed from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005740 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005741 int mLoadedNumCrashes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005742
5743 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005744 * Number of times the process has had an ANR from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005745 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005746 int mLoadedNumAnrs;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005747
5748 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005749 * The amount of user time when last unplugged.
5750 */
5751 long mUnpluggedUserTime;
5752
5753 /**
5754 * The amount of system time when last unplugged.
5755 */
5756 long mUnpluggedSystemTime;
5757
5758 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005759 * The amount of foreground time since unplugged.
5760 */
5761 long mUnpluggedForegroundTime;
5762
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005763 /**
5764 * The number of times the process has started before unplugged.
5765 */
5766 int mUnpluggedStarts;
5767
Dianne Hackborn61659e52014-07-09 16:13:01 -07005768 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005769 * Number of times the process has crashed before unplugged.
5770 */
5771 int mUnpluggedNumCrashes;
5772
5773 /**
5774 * Number of times the process has had an ANR before unplugged.
5775 */
5776 int mUnpluggedNumAnrs;
5777
5778 /**
Dianne Hackborn61659e52014-07-09 16:13:01 -07005779 * Current process state.
5780 */
5781 int mProcessState = PROCESS_STATE_NONE;
5782
Amith Yamasanie43530a2009-08-21 13:11:37 -07005783 SamplingCounter[] mSpeedBins;
5784
Dianne Hackborn287952c2010-09-22 22:34:31 -07005785 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005786
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005787 Proc(String name) {
5788 mName = name;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005789 mOnBatteryTimeBase.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07005790 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005791 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005792
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005793 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005794 mUnpluggedUserTime = mUserTime;
5795 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005796 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005797 mUnpluggedStarts = mStarts;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005798 mUnpluggedNumCrashes = mNumCrashes;
5799 mUnpluggedNumAnrs = mNumAnrs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005800 }
5801
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005802 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005803 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005804
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005805 void reset() {
5806 mUserTime = mSystemTime = mForegroundTime = 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005807 mStarts = mNumCrashes = mNumAnrs = 0;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005808 mLoadedUserTime = mLoadedSystemTime = mLoadedForegroundTime = 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005809 mLoadedStarts = mLoadedNumCrashes = mLoadedNumAnrs = 0;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005810 mUnpluggedUserTime = mUnpluggedSystemTime = mUnpluggedForegroundTime = 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005811 mUnpluggedStarts = mUnpluggedNumCrashes = mUnpluggedNumAnrs = 0;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005812 for (int i = 0; i < mSpeedBins.length; i++) {
5813 SamplingCounter c = mSpeedBins[i];
5814 if (c != null) {
5815 c.reset(false);
5816 }
5817 }
5818 mExcessivePower = null;
5819 }
5820
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005821 void detach() {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005822 mActive = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005823 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005824 for (int i = 0; i < mSpeedBins.length; i++) {
5825 SamplingCounter c = mSpeedBins[i];
5826 if (c != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005827 mOnBatteryTimeBase.remove(c);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005828 mSpeedBins[i] = null;
5829 }
5830 }
5831 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005832
Dianne Hackborn287952c2010-09-22 22:34:31 -07005833 public int countExcessivePowers() {
5834 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005835 }
5836
Dianne Hackborn287952c2010-09-22 22:34:31 -07005837 public ExcessivePower getExcessivePower(int i) {
5838 if (mExcessivePower != null) {
5839 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005840 }
5841 return null;
5842 }
5843
5844 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005845 if (mExcessivePower == null) {
5846 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005847 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005848 ExcessivePower ew = new ExcessivePower();
5849 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005850 ew.overTime = overTime;
5851 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07005852 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005853 }
5854
Dianne Hackborn287952c2010-09-22 22:34:31 -07005855 public void addExcessiveCpu(long overTime, long usedTime) {
5856 if (mExcessivePower == null) {
5857 mExcessivePower = new ArrayList<ExcessivePower>();
5858 }
5859 ExcessivePower ew = new ExcessivePower();
5860 ew.type = ExcessivePower.TYPE_CPU;
5861 ew.overTime = overTime;
5862 ew.usedTime = usedTime;
5863 mExcessivePower.add(ew);
5864 }
5865
5866 void writeExcessivePowerToParcelLocked(Parcel out) {
5867 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005868 out.writeInt(0);
5869 return;
5870 }
5871
Dianne Hackborn287952c2010-09-22 22:34:31 -07005872 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005873 out.writeInt(N);
5874 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005875 ExcessivePower ew = mExcessivePower.get(i);
5876 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005877 out.writeLong(ew.overTime);
5878 out.writeLong(ew.usedTime);
5879 }
5880 }
5881
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005882 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005883 final int N = in.readInt();
5884 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005885 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005886 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005887 }
5888
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005889 if (N > 10000) {
5890 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
5891 return false;
5892 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07005893
Dianne Hackborn287952c2010-09-22 22:34:31 -07005894 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005895 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005896 ExcessivePower ew = new ExcessivePower();
5897 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005898 ew.overTime = in.readLong();
5899 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07005900 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005901 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005902 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005903 }
5904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005905 void writeToParcelLocked(Parcel out) {
5906 out.writeLong(mUserTime);
5907 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005908 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005909 out.writeInt(mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005910 out.writeInt(mNumCrashes);
5911 out.writeInt(mNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 out.writeLong(mLoadedUserTime);
5913 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005914 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005915 out.writeInt(mLoadedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005916 out.writeInt(mLoadedNumCrashes);
5917 out.writeInt(mLoadedNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005918 out.writeLong(mUnpluggedUserTime);
5919 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005920 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005921 out.writeInt(mUnpluggedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005922 out.writeInt(mUnpluggedNumCrashes);
5923 out.writeInt(mUnpluggedNumAnrs);
Amith Yamasanie43530a2009-08-21 13:11:37 -07005924
5925 out.writeInt(mSpeedBins.length);
5926 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005927 SamplingCounter c = mSpeedBins[i];
5928 if (c != null) {
5929 out.writeInt(1);
5930 c.writeToParcel(out);
5931 } else {
5932 out.writeInt(0);
5933 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005934 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005935
Dianne Hackborn287952c2010-09-22 22:34:31 -07005936 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005937 }
5938
5939 void readFromParcelLocked(Parcel in) {
5940 mUserTime = in.readLong();
5941 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005942 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005943 mStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005944 mNumCrashes = in.readInt();
5945 mNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005946 mLoadedUserTime = in.readLong();
5947 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005948 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005949 mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005950 mLoadedNumCrashes = in.readInt();
5951 mLoadedNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005952 mUnpluggedUserTime = in.readLong();
5953 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005954 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005955 mUnpluggedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005956 mUnpluggedNumCrashes = in.readInt();
5957 mUnpluggedNumAnrs = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07005958
5959 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005960 int steps = getCpuSpeedSteps();
5961 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07005962 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005963 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005964 mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005965 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005966 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005967
Dianne Hackborn287952c2010-09-22 22:34:31 -07005968 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005969 }
5970
5971 public BatteryStatsImpl getBatteryStats() {
5972 return BatteryStatsImpl.this;
5973 }
5974
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005975 public void addCpuTimeLocked(int utime, int stime, long[] speedStepBins) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005976 mUserTime += utime;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005977 mCurStepUserTime += utime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 mSystemTime += stime;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005979 mCurStepSystemTime += stime;
5980
5981 for (int i = 0; i < mSpeedBins.length && i < speedStepBins.length; i++) {
5982 long amt = speedStepBins[i];
5983 if (amt != 0) {
5984 SamplingCounter c = mSpeedBins[i];
5985 if (c == null) {
5986 mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase);
5987 }
5988 c.addCountAtomic(speedStepBins[i]);
5989 }
5990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005991 }
5992
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005993 public void addForegroundTimeLocked(long ttime) {
5994 mForegroundTime += ttime;
5995 }
5996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005997 public void incStartsLocked() {
5998 mStarts++;
5999 }
6000
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006001 public void incNumCrashesLocked() {
6002 mNumCrashes++;
6003 }
6004
6005 public void incNumAnrsLocked() {
6006 mNumAnrs++;
6007 }
6008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006009 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08006010 public boolean isActive() {
6011 return mActive;
6012 }
6013
6014 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006015 public long getUserTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006016 long val = mUserTime;
6017 if (which == STATS_CURRENT) {
6018 val -= mLoadedUserTime;
6019 } else if (which == STATS_SINCE_UNPLUGGED) {
6020 val -= mUnpluggedUserTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006021 }
6022 return val;
6023 }
6024
6025 @Override
6026 public long getSystemTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006027 long val = mSystemTime;
6028 if (which == STATS_CURRENT) {
6029 val -= mLoadedSystemTime;
6030 } else if (which == STATS_SINCE_UNPLUGGED) {
6031 val -= mUnpluggedSystemTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006032 }
6033 return val;
6034 }
6035
6036 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006037 public long getForegroundTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006038 long val = mForegroundTime;
6039 if (which == STATS_CURRENT) {
6040 val -= mLoadedForegroundTime;
6041 } else if (which == STATS_SINCE_UNPLUGGED) {
6042 val -= mUnpluggedForegroundTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006043 }
6044 return val;
6045 }
6046
6047 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006049 int val = mStarts;
6050 if (which == STATS_CURRENT) {
6051 val -= mLoadedStarts;
6052 } else if (which == STATS_SINCE_UNPLUGGED) {
6053 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006054 }
6055 return val;
6056 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006057
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006058 @Override
6059 public int getNumCrashes(int which) {
6060 int val = mNumCrashes;
6061 if (which == STATS_CURRENT) {
6062 val -= mLoadedNumCrashes;
6063 } else if (which == STATS_SINCE_UNPLUGGED) {
6064 val -= mUnpluggedNumCrashes;
6065 }
6066 return val;
6067 }
6068
6069 @Override
6070 public int getNumAnrs(int which) {
6071 int val = mNumAnrs;
6072 if (which == STATS_CURRENT) {
6073 val -= mLoadedNumAnrs;
6074 } else if (which == STATS_SINCE_UNPLUGGED) {
6075 val -= mUnpluggedNumAnrs;
6076 }
6077 return val;
6078 }
6079
Amith Yamasanie43530a2009-08-21 13:11:37 -07006080 @Override
6081 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
6082 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006083 SamplingCounter c = mSpeedBins[speedStep];
6084 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07006085 } else {
6086 return 0;
6087 }
6088 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006089 }
6090
6091 /**
6092 * The statistics associated with a particular package.
6093 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006094 public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006095 /**
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006096 * Number of times wakeup alarms have occurred for this app.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006097 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006098 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006099
6100 /**
6101 * The statics we have collected for this package's services.
6102 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006103 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006104
6105 Pkg() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006106 mOnBatteryScreenOffTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006107 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006108
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006109 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006110 }
6111
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006112 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006114
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006115 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006116 mOnBatteryScreenOffTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006117 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006119 void readFromParcelLocked(Parcel in) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006120 int numWA = in.readInt();
6121 mWakeupAlarms.clear();
6122 for (int i=0; i<numWA; i++) {
6123 String tag = in.readString();
6124 mWakeupAlarms.put(tag, new Counter(mOnBatteryTimeBase, in));
6125 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006126
6127 int numServs = in.readInt();
6128 mServiceStats.clear();
6129 for (int m = 0; m < numServs; m++) {
6130 String serviceName = in.readString();
6131 Uid.Pkg.Serv serv = new Serv();
6132 mServiceStats.put(serviceName, serv);
6133
6134 serv.readFromParcelLocked(in);
6135 }
6136 }
6137
6138 void writeToParcelLocked(Parcel out) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006139 int numWA = mWakeupAlarms.size();
6140 out.writeInt(numWA);
6141 for (int i=0; i<numWA; i++) {
6142 out.writeString(mWakeupAlarms.keyAt(i));
6143 mWakeupAlarms.valueAt(i).writeToParcel(out);
6144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006145
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006146 final int NS = mServiceStats.size();
6147 out.writeInt(NS);
6148 for (int i=0; i<NS; i++) {
6149 out.writeString(mServiceStats.keyAt(i));
6150 Uid.Pkg.Serv serv = mServiceStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006151 serv.writeToParcelLocked(out);
6152 }
6153 }
6154
6155 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006156 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() {
6157 return mWakeupAlarms;
6158 }
6159
6160 public void noteWakeupAlarmLocked(String tag) {
6161 Counter c = mWakeupAlarms.get(tag);
6162 if (c == null) {
6163 c = new Counter(mOnBatteryTimeBase);
6164 mWakeupAlarms.put(tag, c);
6165 }
6166 c.stepAtomic();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006167 }
6168
6169 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006170 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
6171 return mServiceStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006172 }
6173
6174 /**
6175 * The statistics associated with a particular service.
6176 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006177 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006178 /**
6179 * Total time (ms in battery uptime) the service has been left started.
6180 */
6181 long mStartTime;
6182
6183 /**
6184 * If service has been started and not yet stopped, this is
6185 * when it was started.
6186 */
6187 long mRunningSince;
6188
6189 /**
6190 * True if we are currently running.
6191 */
6192 boolean mRunning;
6193
6194 /**
6195 * Total number of times startService() has been called.
6196 */
6197 int mStarts;
6198
6199 /**
6200 * Total time (ms in battery uptime) the service has been left launched.
6201 */
6202 long mLaunchedTime;
6203
6204 /**
6205 * If service has been launched and not yet exited, this is
6206 * when it was launched (ms in battery uptime).
6207 */
6208 long mLaunchedSince;
6209
6210 /**
6211 * True if we are currently launched.
6212 */
6213 boolean mLaunched;
6214
6215 /**
6216 * Total number times the service has been launched.
6217 */
6218 int mLaunches;
6219
6220 /**
6221 * The amount of time spent started loaded from a previous save
6222 * (ms in battery uptime).
6223 */
6224 long mLoadedStartTime;
6225
6226 /**
6227 * The number of starts loaded from a previous save.
6228 */
6229 int mLoadedStarts;
6230
6231 /**
6232 * The number of launches loaded from a previous save.
6233 */
6234 int mLoadedLaunches;
6235
6236 /**
6237 * The amount of time spent started as of the last run (ms
6238 * in battery uptime).
6239 */
6240 long mLastStartTime;
6241
6242 /**
6243 * The number of starts as of the last run.
6244 */
6245 int mLastStarts;
6246
6247 /**
6248 * The number of launches as of the last run.
6249 */
6250 int mLastLaunches;
6251
6252 /**
6253 * The amount of time spent started when last unplugged (ms
6254 * in battery uptime).
6255 */
6256 long mUnpluggedStartTime;
6257
6258 /**
6259 * The number of starts when last unplugged.
6260 */
6261 int mUnpluggedStarts;
6262
6263 /**
6264 * The number of launches when last unplugged.
6265 */
6266 int mUnpluggedLaunches;
6267
6268 Serv() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006269 mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006270 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006271
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006272 public void onTimeStarted(long elapsedRealtime, long baseUptime,
6273 long baseRealtime) {
6274 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006275 mUnpluggedStarts = mStarts;
6276 mUnpluggedLaunches = mLaunches;
6277 }
6278
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006279 public void onTimeStopped(long elapsedRealtime, long baseUptime,
6280 long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006281 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006282
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006283 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006284 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006285 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006287 void readFromParcelLocked(Parcel in) {
6288 mStartTime = in.readLong();
6289 mRunningSince = in.readLong();
6290 mRunning = in.readInt() != 0;
6291 mStarts = in.readInt();
6292 mLaunchedTime = in.readLong();
6293 mLaunchedSince = in.readLong();
6294 mLaunched = in.readInt() != 0;
6295 mLaunches = in.readInt();
6296 mLoadedStartTime = in.readLong();
6297 mLoadedStarts = in.readInt();
6298 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006299 mLastStartTime = 0;
6300 mLastStarts = 0;
6301 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006302 mUnpluggedStartTime = in.readLong();
6303 mUnpluggedStarts = in.readInt();
6304 mUnpluggedLaunches = in.readInt();
6305 }
6306
6307 void writeToParcelLocked(Parcel out) {
6308 out.writeLong(mStartTime);
6309 out.writeLong(mRunningSince);
6310 out.writeInt(mRunning ? 1 : 0);
6311 out.writeInt(mStarts);
6312 out.writeLong(mLaunchedTime);
6313 out.writeLong(mLaunchedSince);
6314 out.writeInt(mLaunched ? 1 : 0);
6315 out.writeInt(mLaunches);
6316 out.writeLong(mLoadedStartTime);
6317 out.writeInt(mLoadedStarts);
6318 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006319 out.writeLong(mUnpluggedStartTime);
6320 out.writeInt(mUnpluggedStarts);
6321 out.writeInt(mUnpluggedLaunches);
6322 }
6323
6324 long getLaunchTimeToNowLocked(long batteryUptime) {
6325 if (!mLaunched) return mLaunchedTime;
6326 return mLaunchedTime + batteryUptime - mLaunchedSince;
6327 }
6328
6329 long getStartTimeToNowLocked(long batteryUptime) {
6330 if (!mRunning) return mStartTime;
6331 return mStartTime + batteryUptime - mRunningSince;
6332 }
6333
6334 public void startLaunchedLocked() {
6335 if (!mLaunched) {
6336 mLaunches++;
6337 mLaunchedSince = getBatteryUptimeLocked();
6338 mLaunched = true;
6339 }
6340 }
6341
6342 public void stopLaunchedLocked() {
6343 if (mLaunched) {
6344 long time = getBatteryUptimeLocked() - mLaunchedSince;
6345 if (time > 0) {
6346 mLaunchedTime += time;
6347 } else {
6348 mLaunches--;
6349 }
6350 mLaunched = false;
6351 }
6352 }
6353
6354 public void startRunningLocked() {
6355 if (!mRunning) {
6356 mStarts++;
6357 mRunningSince = getBatteryUptimeLocked();
6358 mRunning = true;
6359 }
6360 }
6361
6362 public void stopRunningLocked() {
6363 if (mRunning) {
6364 long time = getBatteryUptimeLocked() - mRunningSince;
6365 if (time > 0) {
6366 mStartTime += time;
6367 } else {
6368 mStarts--;
6369 }
6370 mRunning = false;
6371 }
6372 }
6373
6374 public BatteryStatsImpl getBatteryStats() {
6375 return BatteryStatsImpl.this;
6376 }
6377
6378 @Override
6379 public int getLaunches(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006380 int val = mLaunches;
6381 if (which == STATS_CURRENT) {
6382 val -= mLoadedLaunches;
6383 } else if (which == STATS_SINCE_UNPLUGGED) {
6384 val -= mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006385 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006386 return val;
6387 }
6388
6389 @Override
6390 public long getStartTime(long now, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006391 long val = getStartTimeToNowLocked(now);
6392 if (which == STATS_CURRENT) {
6393 val -= mLoadedStartTime;
6394 } else if (which == STATS_SINCE_UNPLUGGED) {
6395 val -= mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006397 return val;
6398 }
6399
6400 @Override
6401 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006402 int val = mStarts;
6403 if (which == STATS_CURRENT) {
6404 val -= mLoadedStarts;
6405 } else if (which == STATS_SINCE_UNPLUGGED) {
6406 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 }
6408
6409 return val;
6410 }
6411 }
6412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006413 final Serv newServiceStatsLocked() {
6414 return new Serv();
6415 }
6416 }
6417
6418 /**
6419 * Retrieve the statistics object for a particular process, creating
6420 * if needed.
6421 */
6422 public Proc getProcessStatsLocked(String name) {
6423 Proc ps = mProcessStats.get(name);
6424 if (ps == null) {
Dianne Hackborncd0e3352014-08-07 17:08:09 -07006425 ps = new Proc(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006426 mProcessStats.put(name, ps);
6427 }
6428
6429 return ps;
6430 }
6431
Dianne Hackborn61659e52014-07-09 16:13:01 -07006432 public void updateProcessStateLocked(String procName, int state, long elapsedRealtimeMs) {
6433 int procState;
6434 if (state <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
6435 procState = PROCESS_STATE_FOREGROUND;
6436 } else if (state <= ActivityManager.PROCESS_STATE_RECEIVER) {
6437 procState = PROCESS_STATE_ACTIVE;
6438 } else {
6439 procState = PROCESS_STATE_RUNNING;
6440 }
6441 updateRealProcessStateLocked(procName, procState, elapsedRealtimeMs);
6442 }
6443
6444 public void updateRealProcessStateLocked(String procName, int procState,
6445 long elapsedRealtimeMs) {
6446 Proc proc = getProcessStatsLocked(procName);
6447 if (proc.mProcessState != procState) {
6448 boolean changed;
6449 if (procState < proc.mProcessState) {
6450 // Has this process become more important? If so,
6451 // we may need to change the uid if the currrent uid proc state
6452 // is not as important as what we are now setting.
6453 changed = mProcessState > procState;
6454 } else {
6455 // Has this process become less important? If so,
6456 // we may need to change the uid if the current uid proc state
6457 // is the same importance as the old setting.
6458 changed = mProcessState == proc.mProcessState;
6459 }
6460 proc.mProcessState = procState;
6461 if (changed) {
6462 // uid's state may have changed; compute what the new state should be.
6463 int uidProcState = PROCESS_STATE_NONE;
6464 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
6465 proc = mProcessStats.valueAt(ip);
6466 if (proc.mProcessState < uidProcState) {
6467 uidProcState = proc.mProcessState;
6468 }
6469 }
6470 updateUidProcessStateLocked(uidProcState, elapsedRealtimeMs);
6471 }
6472 }
6473 }
6474
Dianne Hackbornb5e31652010-09-07 12:13:55 -07006475 public SparseArray<? extends Pid> getPidStats() {
6476 return mPids;
6477 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006478
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006479 public Pid getPidStatsLocked(int pid) {
6480 Pid p = mPids.get(pid);
6481 if (p == null) {
6482 p = new Pid();
6483 mPids.put(pid, p);
6484 }
6485 return p;
6486 }
6487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006488 /**
6489 * Retrieve the statistics object for a particular service, creating
6490 * if needed.
6491 */
6492 public Pkg getPackageStatsLocked(String name) {
6493 Pkg ps = mPackageStats.get(name);
6494 if (ps == null) {
6495 ps = new Pkg();
6496 mPackageStats.put(name, ps);
6497 }
6498
6499 return ps;
6500 }
6501
6502 /**
6503 * Retrieve the statistics object for a particular service, creating
6504 * if needed.
6505 */
6506 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
6507 Pkg ps = getPackageStatsLocked(pkg);
6508 Pkg.Serv ss = ps.mServiceStats.get(serv);
6509 if (ss == null) {
6510 ss = ps.newServiceStatsLocked();
6511 ps.mServiceStats.put(serv, ss);
6512 }
6513
6514 return ss;
6515 }
6516
Dianne Hackbornd953c532014-08-16 18:17:38 -07006517 public void readSyncSummaryFromParcelLocked(String name, Parcel in) {
6518 StopwatchTimer timer = mSyncStats.instantiateObject();
6519 timer.readSummaryFromParcelLocked(in);
6520 mSyncStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006521 }
6522
Dianne Hackbornd953c532014-08-16 18:17:38 -07006523 public void readJobSummaryFromParcelLocked(String name, Parcel in) {
6524 StopwatchTimer timer = mJobStats.instantiateObject();
6525 timer.readSummaryFromParcelLocked(in);
6526 mJobStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006527 }
6528
Dianne Hackbornd953c532014-08-16 18:17:38 -07006529 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) {
6530 Wakelock wl = new Wakelock();
6531 mWakelockStats.add(wlName, wl);
6532 if (in.readInt() != 0) {
6533 wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006534 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006535 if (in.readInt() != 0) {
6536 wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
6537 }
6538 if (in.readInt() != 0) {
6539 wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006540 }
6541 }
6542
Evan Millarc64edde2009-04-18 12:26:32 -07006543 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006544 Sensor se = mSensorStats.get(sensor);
6545 if (se == null) {
6546 if (!create) {
6547 return null;
6548 }
6549 se = new Sensor(sensor);
6550 mSensorStats.put(sensor, se);
6551 }
Evan Millarc64edde2009-04-18 12:26:32 -07006552 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006553 if (t != null) {
6554 return t;
6555 }
Evan Millarc64edde2009-04-18 12:26:32 -07006556 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006557 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07006558 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006559 mSensorTimers.put(sensor, timers);
6560 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006561 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006562 se.mTimer = t;
6563 return t;
6564 }
6565
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006566 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006567 StopwatchTimer t = mSyncStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006568 if (t != null) {
6569 t.startRunningLocked(elapsedRealtimeMs);
6570 }
6571 }
6572
6573 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006574 StopwatchTimer t = mSyncStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006575 if (t != null) {
6576 t.stopRunningLocked(elapsedRealtimeMs);
6577 }
6578 }
6579
6580 public void noteStartJobLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07006581 StopwatchTimer t = mJobStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006582 if (t != null) {
6583 t.startRunningLocked(elapsedRealtimeMs);
6584 }
6585 }
6586
6587 public void noteStopJobLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006588 StopwatchTimer t = mJobStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006589 if (t != null) {
6590 t.stopRunningLocked(elapsedRealtimeMs);
6591 }
6592 }
6593
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006594 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006595 Wakelock wl = mWakelockStats.startObject(name);
6596 if (wl != null) {
6597 wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006598 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07006599 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006600 Pid p = getPidStatsLocked(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006601 if (p.mWakeNesting++ == 0) {
6602 p.mWakeStartMs = elapsedRealtimeMs;
Dianne Hackbornb8071d792010-09-09 16:45:15 -07006603 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006605 }
6606
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006607 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006608 Wakelock wl = mWakelockStats.stopObject(name);
6609 if (wl != null) {
6610 wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006611 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07006612 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006613 Pid p = mPids.get(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006614 if (p != null && p.mWakeNesting > 0) {
6615 if (p.mWakeNesting-- == 1) {
6616 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
6617 p.mWakeStartMs = 0;
6618 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006619 }
6620 }
6621 }
6622
6623 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
6624 Proc p = getProcessStatsLocked(proc);
6625 if (p != null) {
6626 p.addExcessiveWake(overTime, usedTime);
6627 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006628 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006629
Dianne Hackborn287952c2010-09-22 22:34:31 -07006630 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
6631 Proc p = getProcessStatsLocked(proc);
6632 if (p != null) {
6633 p.addExcessiveCpu(overTime, usedTime);
6634 }
6635 }
6636
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006637 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006638 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006639 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006640 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006641 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006642 }
6643
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006644 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006645 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07006646 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006647 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006648 t.stopRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006649 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006650 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006651
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006652 public void noteStartGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006653 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006654 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006655 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006656 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006657 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006658
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006659 public void noteStopGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006660 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006661 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006662 t.stopRunningLocked(elapsedRealtimeMs);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07006663 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006664 }
6665
6666 public BatteryStatsImpl getBatteryStats() {
6667 return BatteryStatsImpl.this;
6668 }
6669 }
6670
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006671 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07006672 if (systemDir != null) {
6673 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"),
6674 new File(systemDir, "batterystats.bin.tmp"));
6675 } else {
6676 mFile = null;
6677 }
6678 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006679 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006680 mExternalSync = externalSync;
Jeff Brown6f357d32014-01-15 20:40:55 -08006681 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006682 mStartCount++;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006683 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006684 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006685 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006686 }
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07006687 mInteractiveTimer = new StopwatchTimer(null, -10, null, mOnBatteryTimeBase);
6688 mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase);
6689 mDeviceIdleModeEnabledTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006690 mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006691 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase);
Wink Saville52840902011-02-18 12:40:47 -08006692 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006693 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null,
6694 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006695 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006696 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006697 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006698 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null,
6699 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006700 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006701 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006702 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6703 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006704 }
Adam Lesinski33dac552015-03-09 15:24:48 -07006705 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
6706 mBluetoothActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6707 mWifiActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6708 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006709 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase);
6710 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006711 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006712 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
6713 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006714 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase);
6715 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006716 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006717 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006718 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07006719 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
6720 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i, null, mOnBatteryTimeBase);
6721 }
6722 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
6723 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i, null,
6724 mOnBatteryTimeBase);
6725 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006726 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
6727 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07006728 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006729 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006730 long uptime = SystemClock.uptimeMillis() * 1000;
6731 long realtime = SystemClock.elapsedRealtime() * 1000;
6732 initTimes(uptime, realtime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07006733 mStartPlatformVersion = mEndPlatformVersion = Build.ID;
Evan Millar633a1742009-04-02 16:36:33 -07006734 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006735 mDischargeUnplugLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006736 mDischargePlugLevel = -1;
Evan Millar633a1742009-04-02 16:36:33 -07006737 mDischargeCurrentLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006738 mCurrentBatteryLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006739 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006740 clearHistoryLocked();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006741 updateDailyDeadlineLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 }
6743
6744 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006745 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07006746 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006747 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07006748 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006749 mExternalSync = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006750 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006751 readFromParcel(p);
6752 }
6753
Adam Lesinskie08af192015-03-25 16:42:59 -07006754 public void setPowerProfile(PowerProfile profile) {
6755 synchronized (this) {
6756 mPowerProfile = profile;
6757 }
6758 }
6759
Dianne Hackborn0d903a82010-09-07 23:51:03 -07006760 public void setCallback(BatteryCallback cb) {
6761 mCallback = cb;
6762 }
6763
Amith Yamasanie43530a2009-08-21 13:11:37 -07006764 public void setNumSpeedSteps(int steps) {
6765 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
6766 }
6767
Amith Yamasanif37447b2009-10-08 18:28:01 -07006768 public void setRadioScanningTimeout(long timeout) {
6769 if (mPhoneSignalScanningTimer != null) {
6770 mPhoneSignalScanningTimer.setTimeout(timeout);
6771 }
6772 }
6773
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006774 public void updateDailyDeadlineLocked() {
6775 // Get the current time.
6776 long currentTime = mDailyStartTime = System.currentTimeMillis();
6777 Calendar calDeadline = Calendar.getInstance();
6778 calDeadline.setTimeInMillis(currentTime);
6779
6780 // Move time up to the next day, ranging from 1am to 3pm.
6781 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1);
6782 calDeadline.set(Calendar.MILLISECOND, 0);
6783 calDeadline.set(Calendar.SECOND, 0);
6784 calDeadline.set(Calendar.MINUTE, 0);
6785 calDeadline.set(Calendar.HOUR_OF_DAY, 1);
6786 mNextMinDailyDeadline = calDeadline.getTimeInMillis();
6787 calDeadline.set(Calendar.HOUR_OF_DAY, 3);
6788 mNextMaxDailyDeadline = calDeadline.getTimeInMillis();
6789 }
6790
6791 public void recordDailyStatsIfNeededLocked(boolean settled) {
6792 long currentTime = System.currentTimeMillis();
6793 if (currentTime >= mNextMaxDailyDeadline) {
6794 recordDailyStatsLocked();
6795 } else if (settled && currentTime >= mNextMinDailyDeadline) {
6796 recordDailyStatsLocked();
6797 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) {
6798 recordDailyStatsLocked();
6799 }
6800 }
6801
6802 public void recordDailyStatsLocked() {
6803 DailyItem item = new DailyItem();
6804 item.mStartTime = mDailyStartTime;
6805 item.mEndTime = System.currentTimeMillis();
6806 boolean hasData = false;
6807 if (mDailyDischargeStepTracker.mNumStepDurations > 0) {
6808 hasData = true;
6809 item.mDischargeSteps = new LevelStepTracker(
6810 mDailyDischargeStepTracker.mNumStepDurations,
6811 mDailyDischargeStepTracker.mStepDurations);
6812 }
6813 if (mDailyChargeStepTracker.mNumStepDurations > 0) {
6814 hasData = true;
6815 item.mChargeSteps = new LevelStepTracker(
6816 mDailyChargeStepTracker.mNumStepDurations,
6817 mDailyChargeStepTracker.mStepDurations);
6818 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006819 if (mDailyPackageChanges != null) {
6820 hasData = true;
6821 item.mPackageChanges = mDailyPackageChanges;
6822 mDailyPackageChanges = null;
6823 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006824 mDailyDischargeStepTracker.init();
6825 mDailyChargeStepTracker.init();
6826 updateDailyDeadlineLocked();
6827
6828 if (hasData) {
6829 mDailyItems.add(item);
6830 while (mDailyItems.size() > MAX_DAILY_ITEMS) {
6831 mDailyItems.remove(0);
6832 }
6833 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
6834 try {
6835 XmlSerializer out = new FastXmlSerializer();
6836 out.setOutput(memStream, "utf-8");
6837 writeDailyItemsLocked(out);
6838 BackgroundThread.getHandler().post(new Runnable() {
6839 @Override
6840 public void run() {
6841 synchronized (mCheckinFile) {
6842 FileOutputStream stream = null;
6843 try {
6844 stream = mDailyFile.startWrite();
6845 memStream.writeTo(stream);
6846 stream.flush();
6847 FileUtils.sync(stream);
6848 stream.close();
6849 mDailyFile.finishWrite(stream);
6850 } catch (IOException e) {
6851 Slog.w("BatteryStats",
6852 "Error writing battery daily items", e);
6853 mDailyFile.failWrite(stream);
6854 }
6855 }
6856 }
6857 });
6858 } catch (IOException e) {
6859 }
6860 }
6861 }
6862
6863 private void writeDailyItemsLocked(XmlSerializer out) throws IOException {
6864 StringBuilder sb = new StringBuilder(64);
6865 out.startDocument(null, true);
6866 out.startTag(null, "daily-items");
6867 for (int i=0; i<mDailyItems.size(); i++) {
6868 final DailyItem dit = mDailyItems.get(i);
6869 out.startTag(null, "item");
6870 out.attribute(null, "start", Long.toString(dit.mStartTime));
6871 out.attribute(null, "end", Long.toString(dit.mEndTime));
6872 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb);
6873 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006874 if (dit.mPackageChanges != null) {
6875 for (int j=0; j<dit.mPackageChanges.size(); j++) {
6876 PackageChange pc = dit.mPackageChanges.get(j);
6877 if (pc.mUpdate) {
6878 out.startTag(null, "upd");
6879 out.attribute(null, "pkg", pc.mPackageName);
6880 out.attribute(null, "ver", Integer.toString(pc.mVersionCode));
6881 out.endTag(null, "upd");
6882 } else {
6883 out.startTag(null, "rem");
6884 out.attribute(null, "pkg", pc.mPackageName);
6885 out.endTag(null, "rem");
6886 }
6887 }
6888 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006889 out.endTag(null, "item");
6890 }
6891 out.endTag(null, "daily-items");
6892 out.endDocument();
6893 }
6894
6895 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps,
6896 StringBuilder tmpBuilder) throws IOException {
6897 if (steps != null) {
6898 out.startTag(null, tag);
6899 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations));
6900 for (int i=0; i<steps.mNumStepDurations; i++) {
6901 out.startTag(null, "s");
6902 tmpBuilder.setLength(0);
6903 steps.encodeEntryAt(i, tmpBuilder);
6904 out.attribute(null, "v", tmpBuilder.toString());
6905 out.endTag(null, "s");
6906 }
6907 out.endTag(null, tag);
6908 }
6909 }
6910
6911 public void readDailyStatsLocked() {
6912 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile());
6913 mDailyItems.clear();
6914 FileInputStream stream;
6915 try {
6916 stream = mDailyFile.openRead();
6917 } catch (FileNotFoundException e) {
6918 return;
6919 }
6920 try {
6921 XmlPullParser parser = Xml.newPullParser();
6922 parser.setInput(stream, null);
6923 readDailyItemsLocked(parser);
6924 } catch (XmlPullParserException e) {
6925 } finally {
6926 try {
6927 stream.close();
6928 } catch (IOException e) {
6929 }
6930 }
6931 }
6932
6933 private void readDailyItemsLocked(XmlPullParser parser) {
6934 try {
6935 int type;
6936 while ((type = parser.next()) != XmlPullParser.START_TAG
6937 && type != XmlPullParser.END_DOCUMENT) {
6938 ;
6939 }
6940
6941 if (type != XmlPullParser.START_TAG) {
6942 throw new IllegalStateException("no start tag found");
6943 }
6944
6945 int outerDepth = parser.getDepth();
6946 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
6947 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
6948 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
6949 continue;
6950 }
6951
6952 String tagName = parser.getName();
6953 if (tagName.equals("item")) {
6954 readDailyItemTagLocked(parser);
6955 } else {
6956 Slog.w(TAG, "Unknown element under <daily-items>: "
6957 + parser.getName());
6958 XmlUtils.skipCurrentTag(parser);
6959 }
6960 }
6961
6962 } catch (IllegalStateException e) {
6963 Slog.w(TAG, "Failed parsing daily " + e);
6964 } catch (NullPointerException e) {
6965 Slog.w(TAG, "Failed parsing daily " + e);
6966 } catch (NumberFormatException e) {
6967 Slog.w(TAG, "Failed parsing daily " + e);
6968 } catch (XmlPullParserException e) {
6969 Slog.w(TAG, "Failed parsing daily " + e);
6970 } catch (IOException e) {
6971 Slog.w(TAG, "Failed parsing daily " + e);
6972 } catch (IndexOutOfBoundsException e) {
6973 Slog.w(TAG, "Failed parsing daily " + e);
6974 }
6975 }
6976
6977 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException,
6978 XmlPullParserException, IOException {
6979 DailyItem dit = new DailyItem();
6980 String attr = parser.getAttributeValue(null, "start");
6981 if (attr != null) {
6982 dit.mStartTime = Long.parseLong(attr);
6983 }
6984 attr = parser.getAttributeValue(null, "end");
6985 if (attr != null) {
6986 dit.mEndTime = Long.parseLong(attr);
6987 }
6988 int outerDepth = parser.getDepth();
6989 int type;
6990 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
6991 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
6992 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
6993 continue;
6994 }
6995
6996 String tagName = parser.getName();
6997 if (tagName.equals("dis")) {
6998 readDailyItemTagDetailsLocked(parser, dit, false, "dis");
6999 } else if (tagName.equals("chg")) {
7000 readDailyItemTagDetailsLocked(parser, dit, true, "chg");
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007001 } else if (tagName.equals("upd")) {
7002 if (dit.mPackageChanges == null) {
7003 dit.mPackageChanges = new ArrayList<>();
7004 }
7005 PackageChange pc = new PackageChange();
7006 pc.mUpdate = true;
7007 pc.mPackageName = parser.getAttributeValue(null, "pkg");
7008 String verStr = parser.getAttributeValue(null, "ver");
7009 pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0;
7010 dit.mPackageChanges.add(pc);
7011 XmlUtils.skipCurrentTag(parser);
7012 } else if (tagName.equals("rem")) {
7013 if (dit.mPackageChanges == null) {
7014 dit.mPackageChanges = new ArrayList<>();
7015 }
7016 PackageChange pc = new PackageChange();
7017 pc.mUpdate = false;
7018 pc.mPackageName = parser.getAttributeValue(null, "pkg");
7019 dit.mPackageChanges.add(pc);
7020 XmlUtils.skipCurrentTag(parser);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007021 } else {
7022 Slog.w(TAG, "Unknown element under <item>: "
7023 + parser.getName());
7024 XmlUtils.skipCurrentTag(parser);
7025 }
7026 }
7027 mDailyItems.add(dit);
7028 }
7029
7030 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge,
7031 String tag)
7032 throws NumberFormatException, XmlPullParserException, IOException {
7033 final String numAttr = parser.getAttributeValue(null, "n");
7034 if (numAttr == null) {
7035 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription());
7036 XmlUtils.skipCurrentTag(parser);
7037 return;
7038 }
7039 final int num = Integer.parseInt(numAttr);
7040 LevelStepTracker steps = new LevelStepTracker(num);
7041 if (isCharge) {
7042 dit.mChargeSteps = steps;
7043 } else {
7044 dit.mDischargeSteps = steps;
7045 }
7046 int i = 0;
7047 int outerDepth = parser.getDepth();
7048 int type;
7049 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
7050 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
7051 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
7052 continue;
7053 }
7054
7055 String tagName = parser.getName();
7056 if ("s".equals(tagName)) {
7057 if (i < num) {
7058 String valueAttr = parser.getAttributeValue(null, "v");
7059 if (valueAttr != null) {
7060 steps.decodeEntryAt(i, valueAttr);
7061 i++;
7062 }
7063 }
7064 } else {
7065 Slog.w(TAG, "Unknown element under <" + tag + ">: "
7066 + parser.getName());
7067 XmlUtils.skipCurrentTag(parser);
7068 }
7069 }
7070 steps.mNumStepDurations = i;
7071 }
7072
7073 @Override
7074 public DailyItem getDailyItemLocked(int daysAgo) {
7075 int index = mDailyItems.size()-1-daysAgo;
7076 return index >= 0 ? mDailyItems.get(index) : null;
7077 }
7078
7079 @Override
7080 public long getCurrentDailyStartTime() {
7081 return mDailyStartTime;
7082 }
7083
7084 @Override
7085 public long getNextMinDailyDeadline() {
7086 return mNextMinDailyDeadline;
7087 }
7088
7089 @Override
7090 public long getNextMaxDailyDeadline() {
7091 return mNextMaxDailyDeadline;
7092 }
7093
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007094 @Override
7095 public boolean startIteratingOldHistoryLocked() {
7096 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
7097 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007098 if ((mHistoryIterator = mHistory) == null) {
7099 return false;
7100 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007101 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007102 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007103 mReadOverflow = false;
7104 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007105 return true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007106 }
7107
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007108 @Override
7109 public boolean getNextOldHistoryLocked(HistoryItem out) {
7110 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
7111 if (!end) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007112 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007113 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007114 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007115 HistoryItem cur = mHistoryIterator;
7116 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007117 if (!mReadOverflow && !end) {
7118 Slog.w(TAG, "Old history ends before new history!");
7119 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007120 return false;
7121 }
7122 out.setTo(cur);
7123 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007124 if (!mReadOverflow) {
7125 if (end) {
7126 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007127 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn8c841092013-06-24 13:46:13 -07007128 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007129 pw.println("Histories differ!");
7130 pw.println("Old history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007131 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007132 pw.println("New history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007133 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false,
7134 true);
Dianne Hackborn8c841092013-06-24 13:46:13 -07007135 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007136 }
7137 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007138 return true;
7139 }
7140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007141 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007142 public void finishIteratingOldHistoryLocked() {
7143 mIteratingHistory = false;
7144 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007145 mHistoryIterator = null;
7146 }
7147
7148 public int getHistoryTotalSize() {
7149 return MAX_HISTORY_BUFFER;
7150 }
7151
7152 public int getHistoryUsedSize() {
7153 return mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007154 }
7155
7156 @Override
7157 public boolean startIteratingHistoryLocked() {
7158 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
7159 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007160 if (mHistoryBuffer.dataSize() <= 0) {
7161 return false;
7162 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007163 mHistoryBuffer.setDataPosition(0);
7164 mReadOverflow = false;
7165 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007166 mReadHistoryStrings = new String[mHistoryTagPool.size()];
7167 mReadHistoryUids = new int[mHistoryTagPool.size()];
7168 mReadHistoryChars = 0;
7169 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
7170 final HistoryTag tag = ent.getKey();
7171 final int idx = ent.getValue();
7172 mReadHistoryStrings[idx] = tag.string;
7173 mReadHistoryUids[idx] = tag.uid;
7174 mReadHistoryChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08007175 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007176 return true;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007177 }
7178
7179 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08007180 public int getHistoryStringPoolSize() {
7181 return mReadHistoryStrings.length;
7182 }
7183
7184 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007185 public int getHistoryStringPoolBytes() {
7186 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
7187 // Each string character is 2 bytes.
7188 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
7189 }
7190
7191 @Override
7192 public String getHistoryTagPoolString(int index) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08007193 return mReadHistoryStrings[index];
7194 }
7195
7196 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007197 public int getHistoryTagPoolUid(int index) {
7198 return mReadHistoryUids[index];
7199 }
7200
7201 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007202 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007203 final int pos = mHistoryBuffer.dataPosition();
7204 if (pos == 0) {
7205 out.clear();
7206 }
7207 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007208 if (end) {
7209 return false;
7210 }
7211
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007212 final long lastRealtime = out.time;
7213 final long lastWalltime = out.currentTime;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007214 readHistoryDelta(mHistoryBuffer, out);
Dianne Hackborn37de0982014-05-09 09:32:18 -07007215 if (out.cmd != HistoryItem.CMD_CURRENT_TIME
7216 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007217 out.currentTime = lastWalltime + (out.time - lastRealtime);
7218 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007219 return true;
7220 }
7221
7222 @Override
7223 public void finishIteratingHistoryLocked() {
7224 mIteratingHistory = false;
7225 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn099bc622014-01-22 13:39:16 -08007226 mReadHistoryStrings = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007227 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007228
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007229 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07007230 public long getHistoryBaseTime() {
7231 return mHistoryBaseTime;
7232 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007233
Dianne Hackbornb5e31652010-09-07 12:13:55 -07007234 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007235 public int getStartCount() {
7236 return mStartCount;
7237 }
7238
7239 public boolean isOnBattery() {
7240 return mOnBattery;
7241 }
7242
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007243 public boolean isCharging() {
7244 return mCharging;
7245 }
7246
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007247 public boolean isScreenOn() {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007248 return mScreenState == Display.STATE_ON;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007249 }
7250
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007251 void initTimes(long uptime, long realtime) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007252 mStartClockTime = System.currentTimeMillis();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007253 mOnBatteryTimeBase.init(uptime, realtime);
7254 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
Dianne Hackborn4590e522014-03-24 13:36:46 -07007255 mRealtime = 0;
7256 mUptime = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007257 mRealtimeStart = realtime;
Dianne Hackborn4590e522014-03-24 13:36:46 -07007258 mUptimeStart = uptime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007259 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007260
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007261 void initDischarge() {
7262 mLowDischargeAmountSinceCharge = 0;
7263 mHighDischargeAmountSinceCharge = 0;
7264 mDischargeAmountScreenOn = 0;
7265 mDischargeAmountScreenOnSinceCharge = 0;
7266 mDischargeAmountScreenOff = 0;
7267 mDischargeAmountScreenOffSinceCharge = 0;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007268 mDischargeStepTracker.init();
7269 mChargeStepTracker.init();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007270 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007271
7272 public void resetAllStatsCmdLocked() {
7273 resetAllStatsLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07007274 final long mSecUptime = SystemClock.uptimeMillis();
7275 long uptime = mSecUptime * 1000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007276 long mSecRealtime = SystemClock.elapsedRealtime();
7277 long realtime = mSecRealtime * 1000;
7278 mDischargeStartLevel = mHistoryCur.batteryLevel;
7279 pullPendingStateUpdatesLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07007280 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007281 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
7282 = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007283 mOnBatteryTimeBase.reset(uptime, realtime);
7284 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
7285 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007286 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007287 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
7288 mDischargeScreenOffUnplugLevel = 0;
7289 } else {
7290 mDischargeScreenOnUnplugLevel = 0;
7291 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
7292 }
7293 mDischargeAmountScreenOn = 0;
7294 mDischargeAmountScreenOff = 0;
7295 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07007296 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007297 }
7298
7299 private void resetAllStatsLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007300 mStartCount = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007301 initTimes(SystemClock.uptimeMillis() * 1000, SystemClock.elapsedRealtime() * 1000);
7302 mScreenOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007303 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007304 mScreenBrightnessTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007305 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007306 mInteractiveTimer.reset(false);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07007307 mPowerSaveModeEnabledTimer.reset(false);
7308 mDeviceIdleModeEnabledTimer.reset(false);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007309 mDeviceIdlingTimer.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007310 mPhoneOnTimer.reset(false);
7311 mAudioOnTimer.reset(false);
7312 mVideoOnTimer.reset(false);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07007313 mFlashlightOnTimer.reset(false);
Wink Saville52840902011-02-18 12:40:47 -08007314 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007315 mPhoneSignalStrengthsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007316 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007317 mPhoneSignalScanningTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007318 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007319 mPhoneDataConnectionsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007320 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007321 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007322 mNetworkByteActivityCounters[i].reset(false);
7323 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007324 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007325 mMobileRadioActiveTimer.reset(false);
7326 mMobileRadioActivePerAppTimer.reset(false);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007327 mMobileRadioActiveAdjustedTime.reset(false);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007328 mMobileRadioActiveUnknownTime.reset(false);
7329 mMobileRadioActiveUnknownCount.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007330 mWifiOnTimer.reset(false);
7331 mGlobalWifiRunningTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007332 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007333 mWifiStateTimer[i].reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007334 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07007335 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
7336 mWifiSupplStateTimer[i].reset(false);
7337 }
7338 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
7339 mWifiSignalStrengthsTimer[i].reset(false);
7340 }
Adam Lesinski33dac552015-03-09 15:24:48 -07007341 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
7342 mBluetoothActivityCounters[i].reset(false);
7343 mWifiActivityCounters[i].reset(false);
7344 }
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007345 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007346
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007347 for (int i=0; i<mUidStats.size(); i++) {
7348 if (mUidStats.valueAt(i).reset()) {
7349 mUidStats.remove(mUidStats.keyAt(i));
7350 i--;
7351 }
7352 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007353
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007354 if (mKernelWakelockStats.size() > 0) {
7355 for (SamplingTimer timer : mKernelWakelockStats.values()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007356 mOnBatteryScreenOffTimeBase.remove(timer);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007357 }
7358 mKernelWakelockStats.clear();
7359 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007360
7361 if (mWakeupReasonStats.size() > 0) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07007362 for (SamplingTimer timer : mWakeupReasonStats.values()) {
7363 mOnBatteryTimeBase.remove(timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007364 }
7365 mWakeupReasonStats.clear();
7366 }
7367
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007368 mLastHistoryStepDetails = null;
7369 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0;
7370 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0;
7371 mLastStepCpuUserTime = mCurStepCpuUserTime = 0;
7372 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0;
7373 mLastStepStatUserTime = mCurStepStatUserTime = 0;
7374 mLastStepStatSystemTime = mCurStepStatSystemTime = 0;
7375 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0;
7376 mLastStepStatIrqTime = mCurStepStatIrqTime = 0;
7377 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0;
7378 mLastStepStatIdleTime = mCurStepStatIdleTime = 0;
7379
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007380 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007381
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007382 clearHistoryLocked();
7383 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007384
Dianne Hackborn40c87252014-03-19 16:55:40 -07007385 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007386 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007387 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) {
7388 // Not recording process starts/stops.
7389 continue;
7390 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07007391 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007392 if (active == null) {
7393 continue;
7394 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07007395 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
7396 SparseIntArray uids = ent.getValue();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007397 for (int j=0; j<uids.size(); j++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07007398 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
7399 uids.keyAt(j));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007400 }
7401 }
7402 }
7403 }
7404
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007405 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007406 if (oldScreenOn) {
7407 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
7408 if (diff > 0) {
7409 mDischargeAmountScreenOn += diff;
7410 mDischargeAmountScreenOnSinceCharge += diff;
7411 }
7412 } else {
7413 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
7414 if (diff > 0) {
7415 mDischargeAmountScreenOff += diff;
7416 mDischargeAmountScreenOffSinceCharge += diff;
7417 }
7418 }
7419 if (newScreenOn) {
7420 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
7421 mDischargeScreenOffUnplugLevel = 0;
7422 } else {
7423 mDischargeScreenOnUnplugLevel = 0;
7424 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
7425 }
7426 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007427
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007428 public void pullPendingStateUpdatesLocked() {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08007429 if (mOnBatteryInternal) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007430 final boolean screenOn = mScreenState == Display.STATE_ON;
7431 updateDischargeScreenLevelsLocked(screenOn, screenOn);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08007432 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007433 }
7434
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007435 private String[] mMobileIfaces = EmptyArray.STRING;
7436 private String[] mWifiIfaces = EmptyArray.STRING;
7437
7438 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
7439
7440 private static final int NETWORK_STATS_LAST = 0;
7441 private static final int NETWORK_STATS_NEXT = 1;
7442 private static final int NETWORK_STATS_DELTA = 2;
7443
7444 private final NetworkStats[] mMobileNetworkStats = new NetworkStats[] {
7445 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7446 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7447 new NetworkStats(SystemClock.elapsedRealtime(), 50)
7448 };
7449
7450 private final NetworkStats[] mWifiNetworkStats = new NetworkStats[] {
7451 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7452 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7453 new NetworkStats(SystemClock.elapsedRealtime(), 50)
7454 };
7455
7456 /**
7457 * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer
7458 * as a buffer of NetworkStats objects to cycle through when computing deltas.
7459 */
7460 private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces,
7461 NetworkStats[] networkStatsBuffer)
7462 throws IOException {
7463 if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED,
7464 false)) {
7465 return null;
7466 }
7467
7468 final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL,
7469 ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]);
7470 networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats,
7471 networkStatsBuffer[NETWORK_STATS_LAST], null, null,
7472 networkStatsBuffer[NETWORK_STATS_DELTA]);
7473 networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST];
7474 networkStatsBuffer[NETWORK_STATS_LAST] = stats;
7475 return networkStatsBuffer[NETWORK_STATS_DELTA];
7476 }
7477
7478 /**
7479 * Distribute WiFi energy info and network traffic to apps.
7480 * @param info The energy information from the WiFi controller.
7481 */
7482 public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) {
Adam Lesinskie08af192015-03-25 16:42:59 -07007483 final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
7484 NetworkStats delta = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007485 try {
Adam Lesinskie08af192015-03-25 16:42:59 -07007486 if (!ArrayUtils.isEmpty(mWifiIfaces)) {
7487 delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats);
7488 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007489 } catch (IOException e) {
7490 Slog.wtf(TAG, "Failed to get wifi network stats", e);
7491 return;
7492 }
7493
7494 if (!mOnBatteryInternal) {
7495 return;
7496 }
7497
Adam Lesinskie08af192015-03-25 16:42:59 -07007498 SparseLongArray rxPackets = new SparseLongArray();
7499 SparseLongArray txPackets = new SparseLongArray();
7500 long totalTxPackets = 0;
7501 long totalRxPackets = 0;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007502 if (delta != null) {
7503 final int size = delta.size();
7504 for (int i = 0; i < size; i++) {
7505 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
7506
Adam Lesinskie08af192015-03-25 16:42:59 -07007507 if (DEBUG_ENERGY) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007508 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
Adam Lesinskie08af192015-03-25 16:42:59 -07007509 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
7510 + " txPackets=" + entry.txPackets);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007511 }
7512
7513 if (entry.rxBytes == 0 || entry.txBytes == 0) {
7514 continue;
7515 }
7516
7517 final Uid u = getUidStatsLocked(mapUid(entry.uid));
7518 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
7519 entry.rxPackets);
7520 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
7521 entry.txPackets);
Adam Lesinskie08af192015-03-25 16:42:59 -07007522 rxPackets.put(u.getUid(), entry.rxPackets);
7523 txPackets.put(u.getUid(), entry.txPackets);
7524
7525 // Sum the total number of packets so that the Rx Power and Tx Power can
7526 // be evenly distributed amongst the apps.
7527 totalRxPackets += entry.rxPackets;
7528 totalTxPackets += entry.txPackets;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007529
7530 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
7531 entry.rxBytes);
7532 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
7533 entry.txBytes);
7534 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
7535 entry.rxPackets);
7536 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
7537 entry.txPackets);
7538 }
7539 }
7540
7541 if (info != null) {
Adam Lesinski17390762015-04-10 13:17:47 -07007542 mHasWifiEnergyReporting = true;
7543
Adam Lesinskie08af192015-03-25 16:42:59 -07007544 // Measured in mAms
7545 final long txTimeMs = info.getControllerTxTimeMillis();
7546 final long rxTimeMs = info.getControllerRxTimeMillis();
7547 final long idleTimeMs = info.getControllerIdleTimeMillis();
7548 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
7549
7550 long leftOverRxTimeMs = rxTimeMs;
7551
7552 if (DEBUG_ENERGY) {
7553 Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
7554 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
7555 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
7556 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
7557 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms");
7558 }
7559
7560 long totalWifiLockTimeMs = 0;
7561 long totalScanTimeMs = 0;
7562
7563 // On the first pass, collect some totals so that we can normalize power
7564 // calculations if we need to.
7565 final int uidStatsSize = mUidStats.size();
7566 for (int i = 0; i < uidStatsSize; i++) {
7567 final Uid uid = mUidStats.valueAt(i);
7568
7569 // Sum the total scan power for all apps.
7570 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
7571 elapsedRealtimeMs * 1000) / 1000;
7572
7573 // Sum the total time holding wifi lock for all apps.
7574 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
7575 elapsedRealtimeMs * 1000) / 1000;
7576 }
7577
7578 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
7579 Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
7580 + rxTimeMs + " ms). Normalizing scan time.");
7581 }
7582
7583 // Actually assign and distribute power usage to apps.
7584 for (int i = 0; i < uidStatsSize; i++) {
7585 final Uid uid = mUidStats.valueAt(i);
7586
7587 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
7588 elapsedRealtimeMs * 1000) / 1000;
7589 if (scanTimeSinceMarkMs > 0) {
7590 // Set the new mark so that next time we get new data since this point.
7591 uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
7592
7593 if (totalScanTimeMs > rxTimeMs) {
7594 // Our total scan time is more than the reported Rx time.
7595 // This is possible because the cost of a scan is approximate.
7596 // Let's normalize the result so that we evenly blame each app
7597 // scanning.
7598 //
7599 // This means that we may have apps that received packets not be blamed
7600 // for this, but this is fine as scans are relatively more expensive.
7601 scanTimeSinceMarkMs = (rxTimeMs * scanTimeSinceMarkMs) / totalScanTimeMs;
7602 }
7603
7604 if (DEBUG_ENERGY) {
7605 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": "
7606 + scanTimeSinceMarkMs + " ms)");
7607 }
7608 uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanTimeSinceMarkMs);
7609 leftOverRxTimeMs -= scanTimeSinceMarkMs;
7610 }
7611
7612 // Distribute evenly the power consumed while Idle to each app holding a WiFi
7613 // lock.
7614 final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
7615 elapsedRealtimeMs * 1000) / 1000;
7616 if (wifiLockTimeSinceMarkMs > 0) {
7617 // Set the new mark so that next time we get new data since this point.
7618 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
7619
7620 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
7621 / totalWifiLockTimeMs;
7622 if (DEBUG_ENERGY) {
7623 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": "
7624 + myIdleTimeMs + " ms");
7625 }
7626 uid.noteWifiControllerActivityLocked(CONTROLLER_IDLE_TIME, myIdleTimeMs);
7627 }
7628 }
7629
7630 if (DEBUG_ENERGY) {
7631 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
7632 }
7633
7634 // Distribute the Tx power appropriately between all apps that transmitted packets.
7635 for (int i = 0; i < txPackets.size(); i++) {
7636 final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
7637 final long myTxTimeMs = (txPackets.valueAt(i) * txTimeMs) / totalTxPackets;
7638 if (DEBUG_ENERGY) {
7639 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
7640 }
7641 uid.noteWifiControllerActivityLocked(CONTROLLER_TX_TIME, myTxTimeMs);
7642 }
7643
7644 // Distribute the remaining Rx power appropriately between all apps that received
7645 // packets.
7646 for (int i = 0; i < rxPackets.size(); i++) {
7647 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i));
7648 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets;
7649 if (DEBUG_ENERGY) {
7650 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
7651 }
7652 uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, myRxTimeMs);
7653 }
7654
7655 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
7656
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007657 // Update WiFi controller stats.
7658 mWifiActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
7659 info.getControllerRxTimeMillis());
7660 mWifiActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
7661 info.getControllerTxTimeMillis());
7662 mWifiActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
7663 info.getControllerIdleTimeMillis());
Adam Lesinskie08af192015-03-25 16:42:59 -07007664
Adam Lesinskie283d332015-04-16 12:29:25 -07007665 final double opVoltage = mPowerProfile.getAveragePower(
7666 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE);
7667 if (opVoltage != 0) {
7668 mWifiActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked(
7669 (long)(info.getControllerEnergyUsed() / opVoltage));
Adam Lesinskie08af192015-03-25 16:42:59 -07007670 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007671 }
7672 }
7673
7674 /**
7675 * Distribute Cell radio energy info and network traffic to apps.
7676 */
Adam Lesinskie08af192015-03-25 16:42:59 -07007677 public void updateMobileRadioStateLocked(final long elapsedRealtimeMs) {
7678 NetworkStats delta = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007679 try {
Adam Lesinskie08af192015-03-25 16:42:59 -07007680 if (!ArrayUtils.isEmpty(mMobileIfaces)) {
7681 delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats);
7682 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007683 } catch (IOException e) {
7684 Slog.wtf(TAG, "Failed to get mobile network stats", e);
7685 return;
7686 }
7687
7688 if (delta == null || !mOnBatteryInternal) {
7689 return;
7690 }
7691
Adam Lesinskie08af192015-03-25 16:42:59 -07007692 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
7693 elapsedRealtimeMs * 1000);
7694 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007695 long totalPackets = delta.getTotalPackets();
7696
7697 final int size = delta.size();
7698 for (int i = 0; i < size; i++) {
7699 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
7700
Adam Lesinskie08af192015-03-25 16:42:59 -07007701 if (entry.rxBytes == 0 || entry.txBytes == 0) {
7702 continue;
7703 }
7704
7705 if (DEBUG_ENERGY) {
7706 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
7707 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
7708 + " txPackets=" + entry.txPackets);
7709 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007710
7711 final Uid u = getUidStatsLocked(mapUid(entry.uid));
7712 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
7713 entry.rxPackets);
7714 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
7715 entry.txPackets);
7716
7717 if (radioTime > 0) {
7718 // Distribute total radio active time in to this app.
7719 long appPackets = entry.rxPackets + entry.txPackets;
7720 long appRadioTime = (radioTime*appPackets)/totalPackets;
7721 u.noteMobileRadioActiveTimeLocked(appRadioTime);
7722 // Remove this app from the totals, so that we don't lose any time
7723 // due to rounding.
7724 radioTime -= appRadioTime;
7725 totalPackets -= appPackets;
7726 }
7727
7728 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
7729 entry.rxBytes);
7730 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
7731 entry.txBytes);
7732 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
7733 entry.rxPackets);
7734 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
7735 entry.txPackets);
7736 }
7737
7738 if (radioTime > 0) {
7739 // Whoops, there is some radio time we can't blame on an app!
7740 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
7741 mMobileRadioActiveUnknownCount.addCountLocked(1);
7742 }
7743 }
7744
7745 /**
7746 * Distribute Bluetooth energy info and network traffic to apps.
7747 * @param info The energy information from the bluetooth controller.
7748 */
7749 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
Adam Lesinskie08af192015-03-25 16:42:59 -07007750 if (info != null && mOnBatteryInternal && false) {
Adam Lesinski17390762015-04-10 13:17:47 -07007751 mHasBluetoothEnergyReporting = true;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007752 mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
7753 info.getControllerRxTimeMillis());
7754 mBluetoothActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
7755 info.getControllerTxTimeMillis());
7756 mBluetoothActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
7757 info.getControllerIdleTimeMillis());
Adam Lesinskie283d332015-04-16 12:29:25 -07007758
7759 final double opVoltage = mPowerProfile.getAveragePower(
7760 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE);
7761 if (opVoltage != 0) {
7762 mBluetoothActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked(
7763 (long) (info.getControllerEnergyUsed() / opVoltage));
7764 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007765 }
7766 }
7767
7768 /**
7769 * Read and distribute kernel wake lock use across apps.
7770 */
7771 public void updateKernelWakelocksLocked() {
7772 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
7773 mTmpWakelockStats);
7774 if (wakelockStats == null) {
7775 // Not crashing might make board bringup easier.
7776 Slog.w(TAG, "Couldn't get kernel wake lock stats");
7777 return;
7778 }
7779
7780 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
7781 String name = ent.getKey();
7782 KernelWakelockStats.Entry kws = ent.getValue();
7783
7784 SamplingTimer kwlt = mKernelWakelockStats.get(name);
7785 if (kwlt == null) {
7786 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
7787 true /* track reported val */);
7788 mKernelWakelockStats.put(name, kwlt);
7789 }
7790 kwlt.updateCurrentReportedCount(kws.mCount);
7791 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
7792 kwlt.setUpdateVersion(kws.mVersion);
7793 }
7794
7795 if (wakelockStats.size() != mKernelWakelockStats.size()) {
7796 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
7797 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
7798 SamplingTimer st = ent.getValue();
7799 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
7800 st.setStale();
7801 }
7802 }
7803 }
7804 }
7805
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007806 boolean setChargingLocked(boolean charging) {
7807 if (mCharging != charging) {
7808 mCharging = charging;
7809 if (charging) {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07007810 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007811 } else {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07007812 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007813 }
7814 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING);
7815 return true;
7816 }
7817 return false;
7818 }
7819
Dianne Hackborn40c87252014-03-19 16:55:40 -07007820 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
7821 final int oldStatus, final int level) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007822 boolean doWrite = false;
7823 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
7824 m.arg1 = onBattery ? 1 : 0;
7825 mHandler.sendMessage(m);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007826
Dianne Hackborn40c87252014-03-19 16:55:40 -07007827 final long uptime = mSecUptime * 1000;
7828 final long realtime = mSecRealtime * 1000;
Jeff Browne95c3cd2014-05-02 16:59:26 -07007829 final boolean screenOn = mScreenState == Display.STATE_ON;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007830 if (onBattery) {
7831 // We will reset our status if we are unplugging after the
7832 // battery was last full, or the level is at 100, or
7833 // we have gone through a significant charge (from a very low
7834 // level to a now very high level).
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007835 boolean reset = false;
Dianne Hackborn9a755432014-05-15 17:05:22 -07007836 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007837 || level >= 90
Dianne Hackbornfb3809c2014-09-29 18:31:22 -07007838 || (mDischargeCurrentLevel < 20 && level >= 80)
7839 || (getHighDischargeAmountSinceCharge() >= 200
7840 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -07007841 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
Dianne Hackbornfb3809c2014-09-29 18:31:22 -07007842 + " dischargeLevel=" + mDischargeCurrentLevel
Dianne Hackborn73d6a822014-09-29 10:52:47 -07007843 + " lowAmount=" + getLowDischargeAmountSinceCharge()
7844 + " highAmount=" + getHighDischargeAmountSinceCharge());
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007845 // Before we write, collect a snapshot of the final aggregated
7846 // stats to be reported in the next checkin. Only do this if we have
7847 // a sufficient amount of data to make it interesting.
7848 if (getLowDischargeAmountSinceCharge() >= 20) {
7849 final Parcel parcel = Parcel.obtain();
7850 writeSummaryToParcel(parcel, true);
7851 BackgroundThread.getHandler().post(new Runnable() {
7852 @Override public void run() {
7853 synchronized (mCheckinFile) {
7854 FileOutputStream stream = null;
7855 try {
7856 stream = mCheckinFile.startWrite();
7857 stream.write(parcel.marshall());
7858 stream.flush();
7859 FileUtils.sync(stream);
7860 stream.close();
7861 mCheckinFile.finishWrite(stream);
7862 } catch (IOException e) {
7863 Slog.w("BatteryStats",
7864 "Error writing checkin battery statistics", e);
7865 mCheckinFile.failWrite(stream);
7866 } finally {
7867 parcel.recycle();
7868 }
7869 }
7870 }
7871 });
7872 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007873 doWrite = true;
7874 resetAllStatsLocked();
7875 mDischargeStartLevel = level;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007876 reset = true;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007877 mDischargeStepTracker.init();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007878 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007879 if (mCharging) {
7880 setChargingLocked(false);
7881 }
7882 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007883 mOnBattery = mOnBatteryInternal = true;
Dianne Hackborn260c5022014-04-29 11:23:16 -07007884 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07007885 mMinDischargeStepLevel = level;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007886 mDischargeStepTracker.clearTime();
7887 mDailyDischargeStepTracker.clearTime();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007888 mInitStepMode = mCurStepMode;
7889 mModStepMode = 0;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007890 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007891 mHistoryCur.batteryLevel = (byte)level;
7892 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
7893 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
7894 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007895 if (reset) {
7896 mRecordingHistory = true;
7897 startRecordingHistory(mSecRealtime, mSecUptime, reset);
7898 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07007899 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007900 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
Jeff Browne95c3cd2014-05-02 16:59:26 -07007901 if (screenOn) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007902 mDischargeScreenOnUnplugLevel = level;
7903 mDischargeScreenOffUnplugLevel = 0;
7904 } else {
7905 mDischargeScreenOnUnplugLevel = 0;
7906 mDischargeScreenOffUnplugLevel = level;
7907 }
7908 mDischargeAmountScreenOn = 0;
7909 mDischargeAmountScreenOff = 0;
Jeff Browne95c3cd2014-05-02 16:59:26 -07007910 updateTimeBasesLocked(true, !screenOn, uptime, realtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007911 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007912 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007913 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007914 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007915 mHistoryCur.batteryLevel = (byte)level;
7916 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
7917 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
7918 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07007919 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007920 mDischargeCurrentLevel = mDischargePlugLevel = level;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007921 if (level < mDischargeUnplugLevel) {
7922 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
7923 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
7924 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007925 updateDischargeScreenLevelsLocked(screenOn, screenOn);
7926 updateTimeBasesLocked(false, !screenOn, uptime, realtime);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007927 mChargeStepTracker.init();
Dianne Hackborn260c5022014-04-29 11:23:16 -07007928 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07007929 mMaxChargeStepLevel = level;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007930 mInitStepMode = mCurStepMode;
7931 mModStepMode = 0;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007932 }
7933 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
7934 if (mFile != null) {
7935 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007936 }
7937 }
7938 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007939
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007940 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
7941 boolean reset) {
7942 mRecordingHistory = true;
7943 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborna7d0d552014-09-12 17:15:52 -07007944 mLastRecordedClockTime = mHistoryCur.currentTime;
7945 mLastRecordedClockRealtime = elapsedRealtimeMs;
Dianne Hackborn37de0982014-05-09 09:32:18 -07007946 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
7947 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007948 mHistoryCur);
7949 mHistoryCur.currentTime = 0;
7950 if (reset) {
7951 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
7952 }
7953 }
7954
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07007955 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs,
7956 final long uptimeMs) {
7957 if (mRecordingHistory) {
7958 mHistoryCur.currentTime = currentTime;
Dianne Hackborna7d0d552014-09-12 17:15:52 -07007959 mLastRecordedClockTime = currentTime;
7960 mLastRecordedClockRealtime = elapsedRealtimeMs;
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07007961 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
7962 mHistoryCur);
7963 mHistoryCur.currentTime = 0;
7964 }
7965 }
7966
Dianne Hackborn29cd7f12015-01-08 10:37:05 -08007967 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
7968 if (mRecordingHistory) {
7969 mHistoryCur.currentTime = System.currentTimeMillis();
7970 mLastRecordedClockTime = mHistoryCur.currentTime;
7971 mLastRecordedClockRealtime = elapsedRealtimeMs;
7972 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN,
7973 mHistoryCur);
7974 mHistoryCur.currentTime = 0;
7975 }
7976 }
7977
Dianne Hackborn0c820db2015-04-14 17:47:34 -07007978 private void scheduleSyncExternalStatsLocked(String reason) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007979 if (mExternalSync != null) {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07007980 mExternalSync.scheduleSync(reason);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007981 }
7982 }
7983
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007984 // This should probably be exposed in the API, though it's not critical
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007985 public static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007986
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007987 public void setBatteryStateLocked(int status, int health, int plugType, int level,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007988 int temp, int volt) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007989 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
7990 final long uptime = SystemClock.uptimeMillis();
7991 final long elapsedRealtime = SystemClock.elapsedRealtime();
7992 if (!mHaveBatteryLevel) {
7993 mHaveBatteryLevel = true;
7994 // We start out assuming that the device is plugged in (not
7995 // on battery). If our first report is now that we are indeed
7996 // plugged in, then twiddle our state to correctly reflect that
7997 // since we won't be going through the full setOnBattery().
7998 if (onBattery == mOnBattery) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07007999 if (onBattery) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008000 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008001 } else {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008002 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008003 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008004 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008005 // Always start out assuming charging, that will be updated later.
Dianne Hackborn0c820db2015-04-14 17:47:34 -07008006 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008007 mHistoryCur.batteryStatus = (byte)status;
8008 mHistoryCur.batteryLevel = (byte)level;
8009 mMaxChargeStepLevel = mMinDischargeStepLevel =
8010 mLastChargeStepLevel = mLastDischargeStepLevel = level;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008011 mLastChargingStateLevel = level;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008012 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
8013 recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
8014 }
8015 int oldStatus = mHistoryCur.batteryStatus;
8016 if (onBattery) {
8017 mDischargeCurrentLevel = level;
8018 if (!mRecordingHistory) {
8019 mRecordingHistory = true;
8020 startRecordingHistory(elapsedRealtime, uptime, true);
8021 }
8022 } else if (level < 96) {
8023 if (!mRecordingHistory) {
8024 mRecordingHistory = true;
8025 startRecordingHistory(elapsedRealtime, uptime, true);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008026 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008027 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008028 mCurrentBatteryLevel = level;
8029 if (mDischargePlugLevel < 0) {
8030 mDischargePlugLevel = level;
Marco Nelissend8593312009-04-30 14:45:06 -07008031 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008032 if (onBattery != mOnBattery) {
8033 mHistoryCur.batteryLevel = (byte)level;
8034 mHistoryCur.batteryStatus = (byte)status;
8035 mHistoryCur.batteryHealth = (byte)health;
8036 mHistoryCur.batteryPlugType = (byte)plugType;
8037 mHistoryCur.batteryTemperature = (short)temp;
8038 mHistoryCur.batteryVoltage = (char)volt;
8039 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
8040 } else {
8041 boolean changed = false;
8042 if (mHistoryCur.batteryLevel != level) {
8043 mHistoryCur.batteryLevel = (byte)level;
8044 changed = true;
Marco Nelissend8593312009-04-30 14:45:06 -07008045
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008046 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
8047 // which will pull external stats.
Dianne Hackborn0c820db2015-04-14 17:47:34 -07008048 scheduleSyncExternalStatsLocked("battery-level");
Evan Millarc64edde2009-04-18 12:26:32 -07008049 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008050 if (mHistoryCur.batteryStatus != status) {
8051 mHistoryCur.batteryStatus = (byte)status;
8052 changed = true;
8053 }
8054 if (mHistoryCur.batteryHealth != health) {
8055 mHistoryCur.batteryHealth = (byte)health;
8056 changed = true;
8057 }
8058 if (mHistoryCur.batteryPlugType != plugType) {
8059 mHistoryCur.batteryPlugType = (byte)plugType;
8060 changed = true;
8061 }
8062 if (temp >= (mHistoryCur.batteryTemperature+10)
8063 || temp <= (mHistoryCur.batteryTemperature-10)) {
8064 mHistoryCur.batteryTemperature = (short)temp;
8065 changed = true;
8066 }
8067 if (volt > (mHistoryCur.batteryVoltage+20)
8068 || volt < (mHistoryCur.batteryVoltage-20)) {
8069 mHistoryCur.batteryVoltage = (char)volt;
8070 changed = true;
8071 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008072 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
8073 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
8074 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
8075 if (onBattery) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008076 changed |= setChargingLocked(false);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008077 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
8078 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
8079 modeBits, elapsedRealtime);
8080 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
8081 modeBits, elapsedRealtime);
8082 mLastDischargeStepLevel = level;
8083 mMinDischargeStepLevel = level;
8084 mInitStepMode = mCurStepMode;
8085 mModStepMode = 0;
8086 }
8087 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008088 if (level >= 90) {
8089 // If the battery level is at least 90%, always consider the device to be
8090 // charging even if it happens to go down a level.
8091 changed |= setChargingLocked(true);
8092 mLastChargeStepLevel = level;
8093 } if (!mCharging) {
8094 if (mLastChargeStepLevel < level) {
8095 // We have not reporting that we are charging, but the level has now
8096 // gone up, so consider the state to be charging.
8097 changed |= setChargingLocked(true);
8098 mLastChargeStepLevel = level;
8099 }
8100 } else {
8101 if (mLastChargeStepLevel > level) {
8102 // We had reported that the device was charging, but here we are with
8103 // power connected and the level going down. Looks like the current
8104 // power supplied isn't enough, so consider the device to now be
8105 // discharging.
8106 changed |= setChargingLocked(false);
8107 mLastChargeStepLevel = level;
8108 }
8109 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008110 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
8111 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
8112 modeBits, elapsedRealtime);
8113 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
8114 modeBits, elapsedRealtime);
8115 mLastChargeStepLevel = level;
8116 mMaxChargeStepLevel = level;
8117 mInitStepMode = mCurStepMode;
8118 mModStepMode = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07008119 }
8120 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008121 if (changed) {
8122 addHistoryRecordLocked(elapsedRealtime, uptime);
8123 }
Evan Millarc64edde2009-04-18 12:26:32 -07008124 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008125 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
8126 // We don't record history while we are plugged in and fully charged.
8127 // The next time we are unplugged, history will be cleared.
8128 mRecordingHistory = DEBUG;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08008129 }
Adam Lesinski33dac552015-03-09 15:24:48 -07008130 }
8131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008132 public long getAwakeTimeBattery() {
8133 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
8134 }
8135
8136 public long getAwakeTimePlugged() {
8137 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
8138 }
8139
8140 @Override
8141 public long computeUptime(long curTime, int which) {
8142 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008143 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008144 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07008145 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008146 }
8147 return 0;
8148 }
8149
8150 @Override
8151 public long computeRealtime(long curTime, int which) {
8152 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008153 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008154 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07008155 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008156 }
8157 return 0;
8158 }
8159
8160 @Override
8161 public long computeBatteryUptime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008162 return mOnBatteryTimeBase.computeUptime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008163 }
8164
8165 @Override
8166 public long computeBatteryRealtime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008167 return mOnBatteryTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008168 }
8169
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008170 @Override
8171 public long computeBatteryScreenOffUptime(long curTime, int which) {
8172 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
8173 }
8174
8175 @Override
8176 public long computeBatteryScreenOffRealtime(long curTime, int which) {
8177 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008178 }
8179
Dianne Hackborn260c5022014-04-29 11:23:16 -07008180 private long computeTimePerLevel(long[] steps, int numSteps) {
8181 // For now we'll do a simple average across all steps.
8182 if (numSteps <= 0) {
8183 return -1;
8184 }
8185 long total = 0;
8186 for (int i=0; i<numSteps; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008187 total += steps[i] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008188 }
8189 return total / numSteps;
8190 /*
8191 long[] buckets = new long[numSteps];
8192 int numBuckets = 0;
8193 int numToAverage = 4;
8194 int i = 0;
8195 while (i < numSteps) {
8196 long totalTime = 0;
8197 int num = 0;
8198 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008199 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008200 num++;
8201 }
8202 buckets[numBuckets] = totalTime / num;
8203 numBuckets++;
8204 numToAverage *= 2;
8205 i += num;
8206 }
8207 if (numBuckets < 1) {
8208 return -1;
8209 }
8210 long averageTime = buckets[numBuckets-1];
8211 for (i=numBuckets-2; i>=0; i--) {
8212 averageTime = (averageTime + buckets[i]) / 2;
8213 }
8214 return averageTime;
8215 */
8216 }
8217
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008218 @Override
8219 public long computeBatteryTimeRemaining(long curTime) {
8220 if (!mOnBattery) {
8221 return -1;
8222 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07008223 /* Simple implementation just looks at the average discharge per level across the
8224 entire sample period.
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008225 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2;
8226 if (discharge < 2) {
8227 return -1;
8228 }
8229 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED);
8230 if (duration < 1000*1000) {
8231 return -1;
8232 }
8233 long usPerLevel = duration/discharge;
8234 return usPerLevel * mCurrentBatteryLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008235 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008236 if (mDischargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008237 return -1;
8238 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008239 long msPerLevel = mDischargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -07008240 if (msPerLevel <= 0) {
8241 return -1;
8242 }
8243 return (msPerLevel * mCurrentBatteryLevel) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008244 }
8245
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008246 @Override
8247 public LevelStepTracker getDischargeLevelStepTracker() {
8248 return mDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008249 }
8250
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008251 @Override
8252 public LevelStepTracker getDailyDischargeLevelStepTracker() {
8253 return mDailyDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008254 }
8255
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008256 @Override
8257 public long computeChargeTimeRemaining(long curTime) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008258 if (mOnBattery) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008259 // Not yet working.
8260 return -1;
8261 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07008262 /* Broken
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008263 int curLevel = mCurrentBatteryLevel;
8264 int plugLevel = mDischargePlugLevel;
8265 if (plugLevel < 0 || curLevel < (plugLevel+1)) {
8266 return -1;
8267 }
8268 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED);
8269 if (duration < 1000*1000) {
8270 return -1;
8271 }
8272 long usPerLevel = duration/(curLevel-plugLevel);
8273 return usPerLevel * (100-curLevel);
Dianne Hackborn260c5022014-04-29 11:23:16 -07008274 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008275 if (mChargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008276 return -1;
8277 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008278 long msPerLevel = mChargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -07008279 if (msPerLevel <= 0) {
8280 return -1;
8281 }
8282 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008283 }
8284
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008285 @Override
8286 public LevelStepTracker getChargeLevelStepTracker() {
8287 return mChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008288 }
8289
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008290 @Override
8291 public LevelStepTracker getDailyChargeLevelStepTracker() {
8292 return mDailyChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008293 }
8294
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008295 @Override
8296 public ArrayList<PackageChange> getDailyPackageChanges() {
8297 return mDailyPackageChanges;
8298 }
8299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008300 long getBatteryUptimeLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008301 return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008302 }
8303
8304 @Override
8305 public long getBatteryUptime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008306 return mOnBatteryTimeBase.getUptime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008307 }
8308
8309 @Override
8310 public long getBatteryRealtime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008311 return mOnBatteryTimeBase.getRealtime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008312 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07008313
The Android Open Source Project10592532009-03-18 17:39:46 -07008314 @Override
Evan Millar633a1742009-04-02 16:36:33 -07008315 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07008316 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07008317 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07008318 }
8319 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008320
Evan Millar633a1742009-04-02 16:36:33 -07008321 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008322 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07008323 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008324
The Android Open Source Project10592532009-03-18 17:39:46 -07008325 @Override
Evan Millar633a1742009-04-02 16:36:33 -07008326 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07008327 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07008328 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07008329 }
8330 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008331
Evan Millar633a1742009-04-02 16:36:33 -07008332 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008333 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07008334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008335
Amith Yamasanie43530a2009-08-21 13:11:37 -07008336 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008337 public int getLowDischargeAmountSinceCharge() {
8338 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008339 int val = mLowDischargeAmountSinceCharge;
8340 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
8341 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
8342 }
8343 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008344 }
8345 }
8346
8347 @Override
8348 public int getHighDischargeAmountSinceCharge() {
8349 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008350 int val = mHighDischargeAmountSinceCharge;
8351 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
8352 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
8353 }
8354 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008355 }
8356 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07008357
8358 @Override
8359 public int getDischargeAmount(int which) {
8360 int dischargeAmount = which == STATS_SINCE_CHARGED
8361 ? getHighDischargeAmountSinceCharge()
8362 : (getDischargeStartLevel() - getDischargeCurrentLevel());
8363 if (dischargeAmount < 0) {
8364 dischargeAmount = 0;
8365 }
8366 return dischargeAmount;
8367 }
8368
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008369 public int getDischargeAmountScreenOn() {
8370 synchronized(this) {
8371 int val = mDischargeAmountScreenOn;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008372 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008373 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
8374 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
8375 }
8376 return val;
8377 }
8378 }
8379
8380 public int getDischargeAmountScreenOnSinceCharge() {
8381 synchronized(this) {
8382 int val = mDischargeAmountScreenOnSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008383 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008384 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
8385 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
8386 }
8387 return val;
8388 }
8389 }
8390
8391 public int getDischargeAmountScreenOff() {
8392 synchronized(this) {
8393 int val = mDischargeAmountScreenOff;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008394 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008395 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
8396 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
8397 }
8398 return val;
8399 }
8400 }
8401
8402 public int getDischargeAmountScreenOffSinceCharge() {
8403 synchronized(this) {
8404 int val = mDischargeAmountScreenOffSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008405 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008406 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
8407 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
8408 }
8409 return val;
8410 }
8411 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008412
8413 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07008414 public int getCpuSpeedSteps() {
8415 return sNumSpeedSteps;
8416 }
8417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008418 /**
8419 * Retrieve the statistics object for a particular uid, creating if needed.
8420 */
8421 public Uid getUidStatsLocked(int uid) {
8422 Uid u = mUidStats.get(uid);
8423 if (u == null) {
8424 u = new Uid(uid);
8425 mUidStats.put(uid, u);
8426 }
8427 return u;
8428 }
8429
8430 /**
8431 * Remove the statistics object for a particular uid.
8432 */
8433 public void removeUidStatsLocked(int uid) {
8434 mUidStats.remove(uid);
8435 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07008436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008437 /**
8438 * Retrieve the statistics object for a particular process, creating
8439 * if needed.
8440 */
8441 public Uid.Proc getProcessStatsLocked(int uid, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008442 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008443 Uid u = getUidStatsLocked(uid);
8444 return u.getProcessStatsLocked(name);
8445 }
8446
8447 /**
8448 * Retrieve the statistics object for a particular process, creating
8449 * if needed.
8450 */
8451 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008452 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008453 Uid u = getUidStatsLocked(uid);
8454 return u.getPackageStatsLocked(pkg);
8455 }
8456
8457 /**
8458 * Retrieve the statistics object for a particular service, creating
8459 * if needed.
8460 */
8461 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008462 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008463 Uid u = getUidStatsLocked(uid);
8464 return u.getServiceStatsLocked(pkg, name);
8465 }
8466
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008467 /**
8468 * Massage data to distribute any reasonable work down to more specific
8469 * owners. Must only be called on a dead BatteryStats object!
8470 */
8471 public void distributeWorkLocked(int which) {
8472 // Aggregate all CPU time associated with WIFI.
8473 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
8474 if (wifiUid != null) {
8475 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
Dianne Hackborn61659e52014-07-09 16:13:01 -07008476 for (int ip=wifiUid.mProcessStats.size()-1; ip>=0; ip--) {
8477 Uid.Proc proc = wifiUid.mProcessStats.valueAt(ip);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008478 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
8479 for (int i=0; i<mUidStats.size(); i++) {
8480 Uid uid = mUidStats.valueAt(i);
8481 if (uid.mUid != Process.WIFI_UID) {
8482 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
8483 if (uidRunningTime > 0) {
8484 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
8485 long time = proc.getUserTime(which);
8486 time = (time*uidRunningTime)/totalRunningTime;
8487 uidProc.mUserTime += time;
8488 proc.mUserTime -= time;
8489 time = proc.getSystemTime(which);
8490 time = (time*uidRunningTime)/totalRunningTime;
8491 uidProc.mSystemTime += time;
8492 proc.mSystemTime -= time;
8493 time = proc.getForegroundTime(which);
8494 time = (time*uidRunningTime)/totalRunningTime;
8495 uidProc.mForegroundTime += time;
8496 proc.mForegroundTime -= time;
8497 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
8498 SamplingCounter sc = proc.mSpeedBins[sb];
8499 if (sc != null) {
8500 time = sc.getCountLocked(which);
8501 time = (time*uidRunningTime)/totalRunningTime;
8502 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
8503 if (uidSc == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008504 uidSc = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008505 uidProc.mSpeedBins[sb] = uidSc;
8506 }
8507 uidSc.mCount.addAndGet((int)time);
8508 sc.mCount.addAndGet((int)-time);
8509 }
8510 }
8511 totalRunningTime -= uidRunningTime;
8512 }
8513 }
8514 }
8515 }
8516 }
8517 }
8518
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008519 public void shutdownLocked() {
Dianne Hackborn29cd7f12015-01-08 10:37:05 -08008520 recordShutdownLocked(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008521 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008522 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008523 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008524
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008525 Parcel mPendingWrite = null;
8526 final ReentrantLock mWriteLock = new ReentrantLock();
8527
8528 public void writeAsyncLocked() {
8529 writeLocked(false);
8530 }
8531
8532 public void writeSyncLocked() {
8533 writeLocked(true);
8534 }
8535
8536 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008537 if (mFile == null) {
8538 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008539 return;
8540 }
8541
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008542 if (mShuttingDown) {
8543 return;
8544 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008545
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008546 Parcel out = Parcel.obtain();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008547 writeSummaryToParcel(out, true);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008548 mLastWriteTime = SystemClock.elapsedRealtime();
8549
8550 if (mPendingWrite != null) {
8551 mPendingWrite.recycle();
8552 }
8553 mPendingWrite = out;
8554
8555 if (sync) {
8556 commitPendingDataToDisk();
8557 } else {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008558 BackgroundThread.getHandler().post(new Runnable() {
8559 @Override public void run() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008560 commitPendingDataToDisk();
8561 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008562 });
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008563 }
8564 }
8565
8566 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07008567 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008568 synchronized (this) {
8569 next = mPendingWrite;
8570 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07008571 if (next == null) {
8572 return;
8573 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008574
8575 mWriteLock.lock();
8576 }
8577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008578 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008579 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008580 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008581 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07008582 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008583 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008584 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008585 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008586 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008587 mFile.rollback();
8588 } finally {
8589 next.recycle();
8590 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07008591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008592 }
8593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008594 public void readLocked() {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008595 if (mDailyFile != null) {
8596 readDailyStatsLocked();
8597 }
8598
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008599 if (mFile == null) {
8600 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008601 return;
8602 }
8603
8604 mUidStats.clear();
8605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008606 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008607 File file = mFile.chooseForRead();
8608 if (!file.exists()) {
8609 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008610 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008611 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008612
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008613 byte[] raw = BatteryStatsHelper.readFully(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008614 Parcel in = Parcel.obtain();
8615 in.unmarshall(raw, 0, raw.length);
8616 in.setDataPosition(0);
8617 stream.close();
8618
8619 readSummaryFromParcel(in);
Dianne Hackborn00e25212014-02-19 10:49:24 -08008620 } catch(Exception e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008621 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008622 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008623
Dianne Hackborncd0e3352014-08-07 17:08:09 -07008624 mEndPlatformVersion = Build.ID;
8625
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008626 if (mHistoryBuffer.dataPosition() > 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008627 mRecordingHistory = true;
Dianne Hackborn40c87252014-03-19 16:55:40 -07008628 final long elapsedRealtime = SystemClock.elapsedRealtime();
8629 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008630 if (USE_OLD_HISTORY) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008631 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008632 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008633 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
8634 startRecordingHistory(elapsedRealtime, uptime, false);
Dianne Hackborne8c88e62011-08-17 19:09:09 -07008635 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008636
8637 recordDailyStatsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 }
8639
8640 public int describeContents() {
8641 return 0;
8642 }
8643
Dianne Hackbornae384452011-06-28 12:33:48 -07008644 void readHistory(Parcel in, boolean andOldHistory) {
8645 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008646
8647 mHistoryBuffer.setDataSize(0);
8648 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008649 mHistoryTagPool.clear();
8650 mNextHistoryTagIdx = 0;
8651 mNumHistoryTagChars = 0;
Dianne Hackborn099bc622014-01-22 13:39:16 -08008652
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008653 int numTags = in.readInt();
8654 for (int i=0; i<numTags; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08008655 int idx = in.readInt();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008656 String str = in.readString();
8657 int uid = in.readInt();
8658 HistoryTag tag = new HistoryTag();
8659 tag.string = str;
8660 tag.uid = uid;
8661 tag.poolIdx = idx;
8662 mHistoryTagPool.put(tag, idx);
8663 if (idx >= mNextHistoryTagIdx) {
8664 mNextHistoryTagIdx = idx+1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08008665 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008666 mNumHistoryTagChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08008667 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008668
8669 int bufSize = in.readInt();
8670 int curPos = in.dataPosition();
8671 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
8672 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
8673 } else if ((bufSize&~3) != bufSize) {
8674 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
8675 } else {
8676 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
8677 + " bytes at " + curPos);
8678 mHistoryBuffer.appendFrom(in, curPos, bufSize);
8679 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008680 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008681
Dianne Hackbornae384452011-06-28 12:33:48 -07008682 if (andOldHistory) {
8683 readOldHistory(in);
8684 }
8685
8686 if (DEBUG_HISTORY) {
8687 StringBuilder sb = new StringBuilder(128);
8688 sb.append("****************** OLD mHistoryBaseTime: ");
8689 TimeUtils.formatDuration(mHistoryBaseTime, sb);
8690 Slog.i(TAG, sb.toString());
8691 }
8692 mHistoryBaseTime = historyBaseTime;
8693 if (DEBUG_HISTORY) {
8694 StringBuilder sb = new StringBuilder(128);
8695 sb.append("****************** NEW mHistoryBaseTime: ");
8696 TimeUtils.formatDuration(mHistoryBaseTime, sb);
8697 Slog.i(TAG, sb.toString());
8698 }
8699
8700 // We are just arbitrarily going to insert 1 minute from the sample of
8701 // the last run until samples in this run.
8702 if (mHistoryBaseTime > 0) {
8703 long oldnow = SystemClock.elapsedRealtime();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008704 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1;
Dianne Hackbornae384452011-06-28 12:33:48 -07008705 if (DEBUG_HISTORY) {
8706 StringBuilder sb = new StringBuilder(128);
8707 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
8708 TimeUtils.formatDuration(mHistoryBaseTime, sb);
8709 Slog.i(TAG, sb.toString());
8710 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07008711 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008712 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008713
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008714 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07008715 if (!USE_OLD_HISTORY) {
8716 return;
8717 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008718 mHistory = mHistoryEnd = mHistoryCache = null;
8719 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07008720 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008721 HistoryItem rec = new HistoryItem(time, in);
8722 addHistoryRecordLocked(rec);
8723 }
8724 }
8725
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008726 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) {
Dianne Hackbornae384452011-06-28 12:33:48 -07008727 if (DEBUG_HISTORY) {
8728 StringBuilder sb = new StringBuilder(128);
8729 sb.append("****************** WRITING mHistoryBaseTime: ");
8730 TimeUtils.formatDuration(mHistoryBaseTime, sb);
Dianne Hackborn40c87252014-03-19 16:55:40 -07008731 sb.append(" mLastHistoryElapsedRealtime: ");
8732 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
Dianne Hackbornae384452011-06-28 12:33:48 -07008733 Slog.i(TAG, sb.toString());
8734 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07008735 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008736 if (!inclData) {
8737 out.writeInt(0);
8738 out.writeInt(0);
8739 return;
8740 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008741 out.writeInt(mHistoryTagPool.size());
8742 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
8743 HistoryTag tag = ent.getKey();
Dianne Hackborn099bc622014-01-22 13:39:16 -08008744 out.writeInt(ent.getValue());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008745 out.writeString(tag.string);
8746 out.writeInt(tag.uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08008747 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008748 out.writeInt(mHistoryBuffer.dataSize());
8749 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
8750 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
8751 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07008752
8753 if (andOldHistory) {
8754 writeOldHistory(out);
8755 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008756 }
8757
8758 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07008759 if (!USE_OLD_HISTORY) {
8760 return;
8761 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008762 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008763 while (rec != null) {
8764 if (rec.time >= 0) rec.writeToParcel(out, 0);
8765 rec = rec.next;
8766 }
8767 out.writeLong(-1);
8768 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008769
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008770 public void readSummaryFromParcel(Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008771 final int version = in.readInt();
8772 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008773 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008774 + ", expected " + VERSION + "; erasing old stats");
8775 return;
8776 }
8777
Dianne Hackbornae384452011-06-28 12:33:48 -07008778 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008780 mStartCount = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008781 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008782 mRealtime = in.readLong();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08008783 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07008784 mStartPlatformVersion = in.readString();
8785 mEndPlatformVersion = in.readString();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008786 mOnBatteryTimeBase.readSummaryFromParcel(in);
8787 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008788 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008789 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07008790 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008791 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008792 mLowDischargeAmountSinceCharge = in.readInt();
8793 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008794 mDischargeAmountScreenOnSinceCharge = in.readInt();
8795 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008796 mDischargeStepTracker.readFromParcel(in);
8797 mChargeStepTracker.readFromParcel(in);
8798 mDailyDischargeStepTracker.readFromParcel(in);
8799 mDailyChargeStepTracker.readFromParcel(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008800 int NPKG = in.readInt();
8801 if (NPKG > 0) {
8802 mDailyPackageChanges = new ArrayList<>(NPKG);
8803 while (NPKG > 0) {
8804 NPKG--;
8805 PackageChange pc = new PackageChange();
8806 pc.mPackageName = in.readString();
8807 pc.mUpdate = in.readInt() != 0;
8808 pc.mVersionCode = in.readInt();
8809 mDailyPackageChanges.add(pc);
8810 }
8811 } else {
8812 mDailyPackageChanges = null;
8813 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008814 mDailyStartTime = in.readLong();
8815 mNextMinDailyDeadline = in.readLong();
8816 mNextMaxDailyDeadline = in.readLong();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008818 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008819
Jeff Browne95c3cd2014-05-02 16:59:26 -07008820 mScreenState = Display.STATE_UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008821 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07008822 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
8823 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
8824 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07008825 mInteractive = false;
8826 mInteractiveTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008827 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07008828 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in);
8829 mDeviceIdleModeEnabledTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008830 mDeviceIdlingTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008831 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08008832 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07008833 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
8834 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07008835 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07008836 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
8837 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
8838 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008839 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08008840 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
8841 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008842 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008843 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08008844 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08008845 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008846 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08008847 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
8848 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07008849 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
The Android Open Source Project10592532009-03-18 17:39:46 -07008850 mWifiOn = false;
8851 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008852 mGlobalWifiRunning = false;
8853 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08008854 for (int i=0; i<NUM_WIFI_STATES; i++) {
8855 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
8856 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07008857 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
8858 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in);
8859 }
8860 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
8861 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
8862 }
Adam Lesinski33dac552015-03-09 15:24:48 -07008863 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
8864 mBluetoothActivityCounters[i].readSummaryFromParcelLocked(in);
8865 }
Adam Lesinski33dac552015-03-09 15:24:48 -07008866 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
8867 mWifiActivityCounters[i].readSummaryFromParcelLocked(in);
8868 }
8869
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008870 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
Dianne Hackbornabc7c492014-06-30 16:57:46 -07008871 mFlashlightOn = false;
8872 mFlashlightOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008873
Evan Millarc64edde2009-04-18 12:26:32 -07008874 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008875 if (NKW > 10000) {
8876 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
8877 return;
8878 }
Evan Millarc64edde2009-04-18 12:26:32 -07008879 for (int ikw = 0; ikw < NKW; ikw++) {
8880 if (in.readInt() != 0) {
8881 String kwltName = in.readString();
8882 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
8883 }
8884 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07008885
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008886 int NWR = in.readInt();
8887 if (NWR > 10000) {
8888 Slog.w(TAG, "File corrupt: too many wakeup reasons " + NWR);
8889 return;
8890 }
8891 for (int iwr = 0; iwr < NWR; iwr++) {
8892 if (in.readInt() != 0) {
8893 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07008894 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008895 }
8896 }
8897
Amith Yamasanie43530a2009-08-21 13:11:37 -07008898 sNumSpeedSteps = in.readInt();
Dianne Hackborn00e25212014-02-19 10:49:24 -08008899 if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) {
8900 throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps);
8901 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07008902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008903 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008904 if (NU > 10000) {
8905 Slog.w(TAG, "File corrupt: too many uids " + NU);
8906 return;
8907 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008908 for (int iu = 0; iu < NU; iu++) {
8909 int uid = in.readInt();
8910 Uid u = new Uid(uid);
8911 mUidStats.put(uid, u);
8912
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008913 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008914 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008915 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008916 }
The Android Open Source Project10592532009-03-18 17:39:46 -07008917 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008918 if (in.readInt() != 0) {
8919 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
8920 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07008921 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008922 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07008923 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008924 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07008925 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
8926 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
8927 if (in.readInt() != 0) {
8928 u.makeWifiBatchedScanBin(i, null);
8929 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
8930 }
8931 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07008932 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008933 if (in.readInt() != 0) {
8934 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
8935 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008936 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08008937 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008938 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008939 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08008940 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
8941 }
8942 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07008943 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
8944 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07008945 u.mProcessState = Uid.PROCESS_STATE_NONE;
8946 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
8947 if (in.readInt() != 0) {
8948 u.makeProcessState(i, null);
8949 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in);
8950 }
8951 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07008952 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08008953 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008954 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07008955
Dianne Hackborn617f8772009-03-31 15:04:46 -07008956 if (in.readInt() != 0) {
8957 if (u.mUserActivityCounters == null) {
8958 u.initUserActivityLocked();
8959 }
8960 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
8961 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
8962 }
8963 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008964
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008965 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08008966 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008967 u.initNetworkActivityLocked();
8968 }
8969 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08008970 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
8971 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008972 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08008973 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
8974 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008975 }
8976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008977 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08008978 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008979 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
8980 return;
8981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008982 for (int iw = 0; iw < NW; iw++) {
8983 String wlName = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07008984 u.readWakeSummaryFromParcelLocked(wlName, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008985 }
8986
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008987 int NS = in.readInt();
8988 if (NS > 100) {
8989 Slog.w(TAG, "File corrupt: too many syncs " + NS);
8990 return;
8991 }
8992 for (int is = 0; is < NS; is++) {
8993 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07008994 u.readSyncSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008995 }
8996
8997 int NJ = in.readInt();
8998 if (NJ > 100) {
8999 Slog.w(TAG, "File corrupt: too many job timers " + NJ);
9000 return;
9001 }
9002 for (int ij = 0; ij < NJ; ij++) {
9003 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07009004 u.readJobSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009005 }
9006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009007 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009008 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009009 Slog.w(TAG, "File corrupt: too many sensors " + NP);
9010 return;
9011 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009012 for (int is = 0; is < NP; is++) {
9013 int seNumber = in.readInt();
9014 if (in.readInt() != 0) {
9015 u.getSensorTimerLocked(seNumber, true)
9016 .readSummaryFromParcelLocked(in);
9017 }
9018 }
9019
9020 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009021 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009022 Slog.w(TAG, "File corrupt: too many processes " + NP);
9023 return;
9024 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009025 for (int ip = 0; ip < NP; ip++) {
9026 String procName = in.readString();
9027 Uid.Proc p = u.getProcessStatsLocked(procName);
9028 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009029 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009030 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009031 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009032 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt();
9033 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009034 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009035 if (NSB > 100) {
9036 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
9037 return;
9038 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009039 p.mSpeedBins = new SamplingCounter[NSB];
9040 for (int i=0; i<NSB; i++) {
9041 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009042 p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009043 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
9044 }
9045 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009046 if (!p.readExcessivePowerFromParcelLocked(in)) {
9047 return;
9048 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009049 }
9050
9051 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009052 if (NP > 10000) {
9053 Slog.w(TAG, "File corrupt: too many packages " + NP);
9054 return;
9055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009056 for (int ip = 0; ip < NP; ip++) {
9057 String pkgName = in.readString();
9058 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009059 final int NWA = in.readInt();
9060 if (NWA > 1000) {
9061 Slog.w(TAG, "File corrupt: too many wakeup alarms " + NWA);
9062 return;
9063 }
9064 p.mWakeupAlarms.clear();
9065 for (int iwa=0; iwa<NWA; iwa++) {
9066 String tag = in.readString();
9067 Counter c = new Counter(mOnBatteryTimeBase);
9068 c.readSummaryFromParcelLocked(in);
9069 p.mWakeupAlarms.put(tag, c);
9070 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009071 NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009072 if (NS > 1000) {
9073 Slog.w(TAG, "File corrupt: too many services " + NS);
9074 return;
9075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009076 for (int is = 0; is < NS; is++) {
9077 String servName = in.readString();
9078 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
9079 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009080 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009081 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009082 }
9083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009084 }
9085 }
9086
9087 /**
9088 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
9089 * disk. This format does not allow a lossless round-trip.
9090 *
9091 * @param out the Parcel to be written to.
9092 */
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009093 public void writeSummaryToParcel(Parcel out, boolean inclHistory) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009094 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009095
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009096 // Pull the clock time. This may update the time and make a new history entry
9097 // if we had originally pulled a time before the RTC was set.
9098 long startClockTime = getStartClockTime();
9099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009100 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
9101 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009102
9103 out.writeInt(VERSION);
9104
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009105 writeHistory(out, inclHistory, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009107 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009108 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009109 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009110 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009111 out.writeString(mStartPlatformVersion);
9112 out.writeString(mEndPlatformVersion);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009113 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
9114 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009115 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009116 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07009117 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009118 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08009119 out.writeInt(getLowDischargeAmountSinceCharge());
9120 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009121 out.writeInt(getDischargeAmountScreenOnSinceCharge());
9122 out.writeInt(getDischargeAmountScreenOffSinceCharge());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009123 mDischargeStepTracker.writeToParcel(out);
9124 mChargeStepTracker.writeToParcel(out);
9125 mDailyDischargeStepTracker.writeToParcel(out);
9126 mDailyChargeStepTracker.writeToParcel(out);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009127 if (mDailyPackageChanges != null) {
9128 final int NPKG = mDailyPackageChanges.size();
9129 out.writeInt(NPKG);
9130 for (int i=0; i<NPKG; i++) {
9131 PackageChange pc = mDailyPackageChanges.get(i);
9132 out.writeString(pc.mPackageName);
9133 out.writeInt(pc.mUpdate ? 1 : 0);
9134 out.writeInt(pc.mVersionCode);
9135 }
9136 } else {
9137 out.writeInt(0);
9138 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009139 out.writeLong(mDailyStartTime);
9140 out.writeLong(mNextMinDailyDeadline);
9141 out.writeLong(mNextMaxDailyDeadline);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009142
9143 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009144 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009145 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009146 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009147 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009148 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9149 mDeviceIdleModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009150 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009151 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Wink Saville52840902011-02-18 12:40:47 -08009152 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009153 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009154 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009155 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009156 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009157 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009158 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009159 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009160 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
9161 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009162 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009163 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9164 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009165 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009166 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
9167 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009168 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9169 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009170 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009171 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009172 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009173 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9174 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9175 }
9176 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9177 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9178 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009179 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9180 mBluetoothActivityCounters[i].writeSummaryFromParcelLocked(out);
9181 }
9182 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9183 mWifiActivityCounters[i].writeSummaryFromParcelLocked(out);
9184 }
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009185 out.writeInt(mNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009186 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009187
Evan Millarc64edde2009-04-18 12:26:32 -07009188 out.writeInt(mKernelWakelockStats.size());
9189 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
9190 Timer kwlt = ent.getValue();
9191 if (kwlt != null) {
9192 out.writeInt(1);
9193 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009194 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9195 } else {
9196 out.writeInt(0);
9197 }
9198 }
9199
9200 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009201 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
9202 SamplingTimer timer = ent.getValue();
9203 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009204 out.writeInt(1);
9205 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009206 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Evan Millarc64edde2009-04-18 12:26:32 -07009207 } else {
9208 out.writeInt(0);
9209 }
9210 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009211
Amith Yamasanie43530a2009-08-21 13:11:37 -07009212 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009213 final int NU = mUidStats.size();
9214 out.writeInt(NU);
9215 for (int iu = 0; iu < NU; iu++) {
9216 out.writeInt(mUidStats.keyAt(iu));
9217 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009218
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009219 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009220 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009221 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009222 } else {
9223 out.writeInt(0);
9224 }
9225 if (u.mFullWifiLockTimer != null) {
9226 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009227 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009228 } else {
9229 out.writeInt(0);
9230 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07009231 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009232 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009233 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009234 } else {
9235 out.writeInt(0);
9236 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07009237 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
9238 if (u.mWifiBatchedScanTimer[i] != null) {
9239 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009240 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Robert Greenwalta029ea12013-09-25 16:38:12 -07009241 } else {
9242 out.writeInt(0);
9243 }
9244 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009245 if (u.mWifiMulticastTimer != null) {
9246 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009247 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009248 } else {
9249 out.writeInt(0);
9250 }
9251 if (u.mAudioTurnedOnTimer != null) {
9252 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009253 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009254 } else {
9255 out.writeInt(0);
9256 }
9257 if (u.mVideoTurnedOnTimer != null) {
9258 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009259 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009260 } else {
9261 out.writeInt(0);
9262 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009263 if (u.mForegroundActivityTimer != null) {
9264 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009265 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009266 } else {
9267 out.writeInt(0);
9268 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07009269 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
9270 if (u.mProcessStateTimer[i] != null) {
9271 out.writeInt(1);
9272 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9273 } else {
9274 out.writeInt(0);
9275 }
9276 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009277 if (u.mVibratorOnTimer != null) {
9278 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009279 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009280 } else {
9281 out.writeInt(0);
9282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009283
Dianne Hackborn617f8772009-03-31 15:04:46 -07009284 if (u.mUserActivityCounters == null) {
9285 out.writeInt(0);
9286 } else {
9287 out.writeInt(1);
9288 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
9289 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
9290 }
9291 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009292
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009293 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009294 out.writeInt(0);
9295 } else {
9296 out.writeInt(1);
9297 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009298 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
9299 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009300 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009301 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
9302 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009303 }
9304
Dianne Hackbornd953c532014-08-16 18:17:38 -07009305 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
9306 int NW = wakeStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009307 out.writeInt(NW);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009308 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009309 out.writeString(wakeStats.keyAt(iw));
9310 Uid.Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009311 if (wl.mTimerFull != null) {
9312 out.writeInt(1);
9313 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9314 } else {
9315 out.writeInt(0);
9316 }
9317 if (wl.mTimerPartial != null) {
9318 out.writeInt(1);
9319 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9320 } else {
9321 out.writeInt(0);
9322 }
9323 if (wl.mTimerWindow != null) {
9324 out.writeInt(1);
9325 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9326 } else {
9327 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009328 }
9329 }
9330
Dianne Hackbornd953c532014-08-16 18:17:38 -07009331 final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap();
9332 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009333 out.writeInt(NS);
9334 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009335 out.writeString(syncStats.keyAt(is));
9336 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009337 }
9338
Dianne Hackbornd953c532014-08-16 18:17:38 -07009339 final ArrayMap<String, StopwatchTimer> jobStats = u.mJobStats.getMap();
9340 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009341 out.writeInt(NJ);
9342 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009343 out.writeString(jobStats.keyAt(ij));
9344 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009345 }
9346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009347 int NSE = u.mSensorStats.size();
9348 out.writeInt(NSE);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009349 for (int ise=0; ise<NSE; ise++) {
9350 out.writeInt(u.mSensorStats.keyAt(ise));
9351 Uid.Sensor se = u.mSensorStats.valueAt(ise);
9352 if (se.mTimer != null) {
9353 out.writeInt(1);
9354 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9355 } else {
9356 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009357 }
9358 }
9359
9360 int NP = u.mProcessStats.size();
9361 out.writeInt(NP);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009362 for (int ip=0; ip<NP; ip++) {
9363 out.writeString(u.mProcessStats.keyAt(ip));
9364 Uid.Proc ps = u.mProcessStats.valueAt(ip);
9365 out.writeLong(ps.mUserTime);
9366 out.writeLong(ps.mSystemTime);
9367 out.writeLong(ps.mForegroundTime);
9368 out.writeInt(ps.mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009369 out.writeInt(ps.mNumCrashes);
9370 out.writeInt(ps.mNumAnrs);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009371 final int N = ps.mSpeedBins.length;
9372 out.writeInt(N);
9373 for (int i=0; i<N; i++) {
9374 if (ps.mSpeedBins[i] != null) {
9375 out.writeInt(1);
9376 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
9377 } else {
9378 out.writeInt(0);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009379 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009380 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07009381 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009382 }
9383
9384 NP = u.mPackageStats.size();
9385 out.writeInt(NP);
9386 if (NP > 0) {
9387 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
9388 : u.mPackageStats.entrySet()) {
9389 out.writeString(ent.getKey());
9390 Uid.Pkg ps = ent.getValue();
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009391 final int NWA = ps.mWakeupAlarms.size();
9392 out.writeInt(NWA);
9393 for (int iwa=0; iwa<NWA; iwa++) {
9394 out.writeString(ps.mWakeupAlarms.keyAt(iwa));
9395 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out);
9396 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009397 NS = ps.mServiceStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009398 out.writeInt(NS);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009399 for (int is=0; is<NS; is++) {
9400 out.writeString(ps.mServiceStats.keyAt(is));
9401 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
9402 long time = ss.getStartTimeToNowLocked(
9403 mOnBatteryTimeBase.getUptime(NOW_SYS));
9404 out.writeLong(time);
9405 out.writeInt(ss.mStarts);
9406 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009407 }
9408 }
9409 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009410 }
9411 }
9412
9413 public void readFromParcel(Parcel in) {
9414 readFromParcelLocked(in);
9415 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009417 void readFromParcelLocked(Parcel in) {
9418 int magic = in.readInt();
9419 if (magic != MAGIC) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009420 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009421 }
9422
Dianne Hackbornae384452011-06-28 12:33:48 -07009423 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009425 mStartCount = in.readInt();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009426 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009427 mStartPlatformVersion = in.readString();
9428 mEndPlatformVersion = in.readString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009429 mUptime = in.readLong();
9430 mUptimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009431 mRealtime = in.readLong();
9432 mRealtimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009433 mOnBattery = in.readInt() != 0;
9434 mOnBatteryInternal = false; // we are no longer really running.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009435 mOnBatteryTimeBase.readFromParcel(in);
9436 mOnBatteryScreenOffTimeBase.readFromParcel(in);
9437
Jeff Browne95c3cd2014-05-02 16:59:26 -07009438 mScreenState = Display.STATE_UNKNOWN;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009439 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase, in);
9440 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
9441 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase,
9442 in);
9443 }
Dianne Hackborn29325132014-05-21 15:01:03 -07009444 mInteractive = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009445 mInteractiveTimer = new StopwatchTimer(null, -10, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009446 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009447 mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
9448 mDeviceIdleModeEnabledTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase, in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009449 mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase, in);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009450 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009451 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
9452 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
9453 null, mOnBatteryTimeBase, in);
9454 }
9455 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase, in);
9456 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
9457 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
9458 null, mOnBatteryTimeBase, in);
9459 }
9460 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
9461 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9462 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9463 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009464 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009465 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in);
9466 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase,
9467 in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009468 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009469 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
9470 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07009471 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009472 mWifiOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009473 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009474 mGlobalWifiRunning = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009475 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009476 for (int i=0; i<NUM_WIFI_STATES; i++) {
9477 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
9478 null, mOnBatteryTimeBase, in);
9479 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009480 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9481 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i,
9482 null, mOnBatteryTimeBase, in);
9483 }
9484 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9485 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i,
9486 null, mOnBatteryTimeBase, in);
9487 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009488 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9489 mBluetoothActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9490 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009491 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9492 mWifiActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9493 }
9494
Adam Lesinski17390762015-04-10 13:17:47 -07009495 mHasWifiEnergyReporting = in.readInt() != 0;
9496 mHasBluetoothEnergyReporting = in.readInt() != 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009497 mNumConnectivityChange = in.readInt();
9498 mLoadedNumConnectivityChange = in.readInt();
9499 mUnpluggedNumConnectivityChange = in.readInt();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07009500 mAudioOnNesting = 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009501 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
Dianne Hackborn10eaa852014-07-22 22:54:55 -07009502 mVideoOnNesting = 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009503 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009504 mFlashlightOn = false;
9505 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009506 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009507 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07009508 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009509 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009510 mLowDischargeAmountSinceCharge = in.readInt();
9511 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009512 mDischargeAmountScreenOn = in.readInt();
9513 mDischargeAmountScreenOnSinceCharge = in.readInt();
9514 mDischargeAmountScreenOff = in.readInt();
9515 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009516 mDischargeStepTracker.readFromParcel(in);
9517 mChargeStepTracker.readFromParcel(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009518 mLastWriteTime = in.readLong();
9519
Evan Millarc64edde2009-04-18 12:26:32 -07009520 mKernelWakelockStats.clear();
9521 int NKW = in.readInt();
9522 for (int ikw = 0; ikw < NKW; ikw++) {
9523 if (in.readInt() != 0) {
9524 String wakelockName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009525 SamplingTimer kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07009526 mKernelWakelockStats.put(wakelockName, kwlt);
9527 }
9528 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009529
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009530 mWakeupReasonStats.clear();
9531 int NWR = in.readInt();
9532 for (int iwr = 0; iwr < NWR; iwr++) {
9533 if (in.readInt() != 0) {
9534 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009535 SamplingTimer timer = new SamplingTimer(mOnBatteryTimeBase, in);
9536 mWakeupReasonStats.put(reasonName, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009537 }
9538 }
9539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009540 mPartialTimers.clear();
9541 mFullTimers.clear();
9542 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009543 mWifiRunningTimers.clear();
9544 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -07009545 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -07009546 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009547 mWifiMulticastTimers.clear();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07009548 mAudioTurnedOnTimers.clear();
9549 mVideoTurnedOnTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009550
Amith Yamasanie43530a2009-08-21 13:11:37 -07009551 sNumSpeedSteps = in.readInt();
9552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009553 int numUids = in.readInt();
9554 mUidStats.clear();
9555 for (int i = 0; i < numUids; i++) {
9556 int uid = in.readInt();
9557 Uid u = new Uid(uid);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009558 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009559 mUidStats.append(uid, u);
9560 }
9561 }
9562
9563 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009564 writeToParcelLocked(out, true, flags);
9565 }
9566
9567 public void writeToParcelWithoutUids(Parcel out, int flags) {
9568 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009569 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009570
9571 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009572 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009573 // Need to update with current kernel wake lock counts.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009574 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009575
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009576 // Pull the clock time. This may update the time and make a new history entry
9577 // if we had originally pulled a time before the RTC was set.
9578 long startClockTime = getStartClockTime();
9579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009580 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
9581 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009582 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
9583 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009585 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009586
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009587 writeHistory(out, true, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009589 out.writeInt(mStartCount);
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009590 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009591 out.writeString(mStartPlatformVersion);
9592 out.writeString(mEndPlatformVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009593 out.writeLong(mUptime);
9594 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009595 out.writeLong(mRealtime);
9596 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009597 out.writeInt(mOnBattery ? 1 : 0);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009598 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
9599 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
9600
9601 mScreenOnTimer.writeToParcel(out, uSecRealtime);
9602 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
9603 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
9604 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009605 mInteractiveTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009606 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime);
9607 mDeviceIdleModeEnabledTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009608 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009609 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
9610 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
9611 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
9612 }
9613 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
9614 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
9615 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
9616 }
9617 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
9618 mNetworkByteActivityCounters[i].writeToParcel(out);
9619 mNetworkPacketActivityCounters[i].writeToParcel(out);
9620 }
9621 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
9622 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009623 mMobileRadioActiveAdjustedTime.writeToParcel(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009624 mMobileRadioActiveUnknownTime.writeToParcel(out);
9625 mMobileRadioActiveUnknownCount.writeToParcel(out);
9626 mWifiOnTimer.writeToParcel(out, uSecRealtime);
9627 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
9628 for (int i=0; i<NUM_WIFI_STATES; i++) {
9629 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
9630 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009631 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9632 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime);
9633 }
9634 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9635 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
9636 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009637 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9638 mBluetoothActivityCounters[i].writeToParcel(out);
9639 }
9640 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9641 mWifiActivityCounters[i].writeToParcel(out);
9642 }
Adam Lesinski17390762015-04-10 13:17:47 -07009643 out.writeInt(mHasWifiEnergyReporting ? 1 : 0);
9644 out.writeInt(mHasBluetoothEnergyReporting ? 1 : 0);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009645 out.writeInt(mNumConnectivityChange);
9646 out.writeInt(mLoadedNumConnectivityChange);
9647 out.writeInt(mUnpluggedNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009648 mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009649 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009650 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07009651 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009652 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009653 out.writeInt(mLowDischargeAmountSinceCharge);
9654 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009655 out.writeInt(mDischargeAmountScreenOn);
9656 out.writeInt(mDischargeAmountScreenOnSinceCharge);
9657 out.writeInt(mDischargeAmountScreenOff);
9658 out.writeInt(mDischargeAmountScreenOffSinceCharge);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009659 mDischargeStepTracker.writeToParcel(out);
9660 mChargeStepTracker.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009661 out.writeLong(mLastWriteTime);
9662
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009663 if (inclUids) {
9664 out.writeInt(mKernelWakelockStats.size());
9665 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
9666 SamplingTimer kwlt = ent.getValue();
9667 if (kwlt != null) {
9668 out.writeInt(1);
9669 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009670 kwlt.writeToParcel(out, uSecRealtime);
9671 } else {
9672 out.writeInt(0);
9673 }
9674 }
9675 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009676 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
9677 SamplingTimer timer = ent.getValue();
9678 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009679 out.writeInt(1);
9680 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009681 timer.writeToParcel(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009682 } else {
9683 out.writeInt(0);
9684 }
Evan Millarc64edde2009-04-18 12:26:32 -07009685 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009686 } else {
9687 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07009688 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07009689
9690 out.writeInt(sNumSpeedSteps);
9691
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009692 if (inclUids) {
9693 int size = mUidStats.size();
9694 out.writeInt(size);
9695 for (int i = 0; i < size; i++) {
9696 out.writeInt(mUidStats.keyAt(i));
9697 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009699 uid.writeToParcelLocked(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009700 }
9701 } else {
9702 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009703 }
9704 }
9705
9706 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
9707 new Parcelable.Creator<BatteryStatsImpl>() {
9708 public BatteryStatsImpl createFromParcel(Parcel in) {
9709 return new BatteryStatsImpl(in);
9710 }
9711
9712 public BatteryStatsImpl[] newArray(int size) {
9713 return new BatteryStatsImpl[size];
9714 }
9715 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009716
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009717 public void prepareForDumpLocked() {
9718 // Need to retrieve current kernel wake lock stats before printing.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009719 pullPendingStateUpdatesLocked();
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009720
9721 // Pull the clock time. This may update the time and make a new history entry
9722 // if we had originally pulled a time before the RTC was set.
9723 getStartClockTime();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009724 }
9725
Dianne Hackbornc51cf032014-03-02 19:08:15 -08009726 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009727 if (DEBUG) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009728 pw.println("mOnBatteryTimeBase:");
9729 mOnBatteryTimeBase.dump(pw, " ");
9730 pw.println("mOnBatteryScreenOffTimeBase:");
9731 mOnBatteryScreenOffTimeBase.dump(pw, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009732 Printer pr = new PrintWriterPrinter(pw);
9733 pr.println("*** Screen timer:");
9734 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07009735 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009736 pr.println("*** Screen brightness #" + i + ":");
9737 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07009738 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009739 pr.println("*** Interactive timer:");
9740 mInteractiveTimer.logState(pr, " ");
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009741 pr.println("*** Power save mode timer:");
9742 mPowerSaveModeEnabledTimer.logState(pr, " ");
9743 pr.println("*** Device idle mode timer:");
9744 mDeviceIdleModeEnabledTimer.logState(pr, " ");
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009745 pr.println("*** Device idling timer:");
9746 mDeviceIdlingTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009747 pr.println("*** Phone timer:");
9748 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08009749 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3251b902014-06-20 14:40:53 -07009750 pr.println("*** Phone signal strength #" + i + ":");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009751 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07009752 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07009753 pr.println("*** Signal scanning :");
9754 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07009755 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009756 pr.println("*** Data connection type #" + i + ":");
9757 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07009758 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009759 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009760 pr.println("*** Mobile network active timer:");
9761 mMobileRadioActiveTimer.logState(pr, " ");
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009762 pr.println("*** Mobile network active adjusted timer:");
9763 mMobileRadioActiveAdjustedTime.logState(pr, " ");
Dianne Hackborn0c820db2015-04-14 17:47:34 -07009764 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009765 pr.println("*** Wifi timer:");
9766 mWifiOnTimer.logState(pr, " ");
9767 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009768 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009769 for (int i=0; i<NUM_WIFI_STATES; i++) {
9770 pr.println("*** Wifi state #" + i + ":");
9771 mWifiStateTimer[i].logState(pr, " ");
9772 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009773 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9774 pr.println("*** Wifi suppl state #" + i + ":");
9775 mWifiSupplStateTimer[i].logState(pr, " ");
9776 }
9777 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9778 pr.println("*** Wifi signal strength #" + i + ":");
9779 mWifiSignalStrengthsTimer[i].logState(pr, " ");
9780 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009781 pr.println("*** Flashlight timer:");
9782 mFlashlightOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009783 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08009784 super.dumpLocked(context, pw, flags, reqUid, histStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009786}