blob: 57220b1e1968f638cd8ec749801c9a4ad6c19b04 [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;
Adam Lesinski50e47602015-12-04 17:04:54 -080022import android.bluetooth.UidTraffic;
Dianne Hackborna7c837f2014-01-15 16:20:44 -080023import android.content.Context;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070024import android.content.Intent;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070025import android.net.ConnectivityManager;
26import android.net.NetworkStats;
Adam Lesinski33dac552015-03-09 15:24:48 -070027import android.net.wifi.WifiActivityEnergyInfo;
Dianne Hackborn3251b902014-06-20 14:40:53 -070028import android.net.wifi.WifiManager;
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;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +010081import java.nio.charset.StandardCharsets;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import java.util.ArrayList;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080083import java.util.Calendar;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070085import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070087import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070088import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089
90/**
91 * All information we are collecting about things that can happen that impact
92 * battery life. All times are represented in microseconds except where indicated
93 * otherwise.
94 */
95public final class BatteryStatsImpl extends BatteryStats {
96 private static final String TAG = "BatteryStatsImpl";
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080097 private static final boolean DEBUG = false;
Adam Lesinskia7c90c82015-06-18 14:52:24 -070098 public static final boolean DEBUG_ENERGY = false;
Adam Lesinski50e47602015-12-04 17:04:54 -080099 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700100 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -0700101 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700102
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700103 // TODO: remove "tcp" from network methods, since we measure total stats.
104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700106 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
108 // Current on-disk Parcel version
Adam Lesinski50e47602015-12-04 17:04:54 -0800109 private static final int VERSION = 139 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700110
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700111 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700112 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700113
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700114 // No, really, THIS is the maximum number of items we will record in the history.
115 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
116
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800117 // The maximum number of names wakelocks we will keep track of
118 // per uid; once the limit is reached, we batch the remaining wakelocks
119 // in to one common name.
Dianne Hackbornacc4a122014-08-18 16:33:44 -0700120 private static final int MAX_WAKELOCKS_PER_UID = 100;
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700121
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
Adam Lesinski06af1fa2015-05-05 17:35:35 -0700134 private final KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
Adam Lesinski6832f392015-09-05 18:05:40 -0700135 private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
Adam Lesinski06af1fa2015-05-05 17:35:35 -0700136
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700137 public interface BatteryCallback {
138 public void batteryNeedsCpuUpdate();
139 public void batteryPowerChanged(boolean onBattery);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700140 public void batterySendBroadcast(Intent intent);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700141 }
142
143 final class MyHandler extends Handler {
Jeff Brown6f357d32014-01-15 20:40:55 -0800144 public MyHandler(Looper looper) {
145 super(looper, null, true);
146 }
147
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700148 @Override
149 public void handleMessage(Message msg) {
150 BatteryCallback cb = mCallback;
151 switch (msg.what) {
152 case MSG_UPDATE_WAKELOCKS:
Adam Lesinski72478f02015-06-17 15:39:43 -0700153 synchronized (BatteryStatsImpl.this) {
154 updateCpuTimeLocked();
155 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700156 if (cb != null) {
157 cb.batteryNeedsCpuUpdate();
158 }
159 break;
160 case MSG_REPORT_POWER_CHANGE:
161 if (cb != null) {
162 cb.batteryPowerChanged(msg.arg1 != 0);
163 }
164 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700165 case MSG_REPORT_CHARGING:
166 if (cb != null) {
167 final String action;
168 synchronized (BatteryStatsImpl.this) {
169 action = mCharging ? BatteryManager.ACTION_CHARGING
170 : BatteryManager.ACTION_DISCHARGING;
171 }
172 Intent intent = new Intent(action);
173 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
174 cb.batterySendBroadcast(intent);
175 }
176 break;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700177 }
178 }
179 }
180
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700181 public interface ExternalStatsSync {
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700182 void scheduleSync(String reason);
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700183 void scheduleWifiSync(String reason);
Adam Lesinski61db88f2015-07-01 15:05:07 -0700184 void scheduleCpuSyncDueToRemovedUid(int uid);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700185 }
186
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700187 public final MyHandler mHandler;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700188 private final ExternalStatsSync mExternalSync;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700189
190 private BatteryCallback mCallback;
191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -0800193 * Mapping isolated uids to the actual owning app uid.
194 */
195 final SparseIntArray mIsolatedUids = new SparseIntArray();
196
197 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 * The statistics we have collected organized by uids.
199 */
Adam Lesinski50e47602015-12-04 17:04:54 -0800200 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201
202 // A set of pools of currently active timers. When a timer is queried, we will divide the
203 // elapsed time by the number of active timers to arrive at that timer's share of the time.
204 // In order to do this, we must refresh each timer whenever the number of active timers
205 // changes.
Adam Lesinskie08af192015-03-25 16:42:59 -0700206 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
207 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
208 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
Jeff Brown6a8bd7b2015-06-19 15:07:51 -0700209 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>();
Adam Lesinskie08af192015-03-25 16:42:59 -0700210 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
211 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
212 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
213 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
214 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
215 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
216 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
217 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700218 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>();
219 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700221 // Last partial timers we use for distributing CPU usage.
Adam Lesinskie08af192015-03-25 16:42:59 -0700222 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 // These are the objects that will want to do something when the device
225 // is unplugged from power.
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800226 final TimeBase mOnBatteryTimeBase = new TimeBase();
227
228 // These are the objects that will want to do something when the device
229 // is unplugged from power *and* the screen is off.
230 final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
231
232 // Set to true when we want to distribute CPU across wakelocks for the next
233 // CPU update, even if we aren't currently running wake locks.
234 boolean mDistributeWakelockCpu;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700235
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700236 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700237
Dianne Hackborn37de0982014-05-09 09:32:18 -0700238 final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800239
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700240 long mHistoryBaseTime;
241 boolean mHaveBatteryLevel = false;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700242 boolean mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700243 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700244
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700245 static final int MAX_HISTORY_BUFFER = 256*1024; // 256KB
246 static final int MAX_MAX_HISTORY_BUFFER = 320*1024; // 320KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700247 final Parcel mHistoryBuffer = Parcel.obtain();
248 final HistoryItem mHistoryLastWritten = new HistoryItem();
249 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700250 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700251 final HistoryItem mHistoryAddTmp = new HistoryItem();
Adam Lesinskie08af192015-03-25 16:42:59 -0700252 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
Dianne Hackborn099bc622014-01-22 13:39:16 -0800253 String[] mReadHistoryStrings;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800254 int[] mReadHistoryUids;
255 int mReadHistoryChars;
256 int mNextHistoryTagIdx = 0;
257 int mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700258 int mHistoryBufferLastPos = -1;
259 boolean mHistoryOverflow = false;
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700260 int mActiveHistoryStates = 0xffffffff;
261 int mActiveHistoryStates2 = 0xffffffff;
Dianne Hackborn40c87252014-03-19 16:55:40 -0700262 long mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700263 long mTrackRunningHistoryElapsedRealtime = 0;
264 long mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700265
266 final HistoryItem mHistoryCur = new HistoryItem();
267
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700268 HistoryItem mHistory;
269 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700270 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700271 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700272
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800273 // Used by computeHistoryStepDetails
274 HistoryStepDetails mLastHistoryStepDetails = null;
275 byte mLastHistoryStepLevel = 0;
276 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
277 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails();
278 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700279
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800280 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700281 * Total time (in milliseconds) spent executing in user code.
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800282 */
283 long mLastStepCpuUserTime;
284 long mCurStepCpuUserTime;
285 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700286 * Total time (in milliseconds) spent executing in kernel code.
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800287 */
288 long mLastStepCpuSystemTime;
289 long mCurStepCpuSystemTime;
290 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700291 * Times from /proc/stat (but measured in milliseconds).
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800292 */
293 long mLastStepStatUserTime;
294 long mLastStepStatSystemTime;
295 long mLastStepStatIOWaitTime;
296 long mLastStepStatIrqTime;
297 long mLastStepStatSoftIrqTime;
298 long mLastStepStatIdleTime;
299 long mCurStepStatUserTime;
300 long mCurStepStatSystemTime;
301 long mCurStepStatIOWaitTime;
302 long mCurStepStatIrqTime;
303 long mCurStepStatSoftIrqTime;
304 long mCurStepStatIdleTime;
305
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700306 private HistoryItem mHistoryIterator;
307 private boolean mReadOverflow;
308 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 int mStartCount;
311
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800312 long mStartClockTime;
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700313 String mStartPlatformVersion;
314 String mEndPlatformVersion;
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 long mUptime;
317 long mUptimeStart;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 long mRealtime;
319 long mRealtimeStart;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700320
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800321 int mWakeLockNesting;
322 boolean mWakeLockImportant;
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700323 public boolean mRecordAllHistory;
Dianne Hackborn9a755432014-05-15 17:05:22 -0700324 boolean mNoAutoReset;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800325
Jeff Browne95c3cd2014-05-02 16:59:26 -0700326 int mScreenState = Display.STATE_UNKNOWN;
Evan Millarc64edde2009-04-18 12:26:32 -0700327 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700328
Dianne Hackborn617f8772009-03-31 15:04:46 -0700329 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700330 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700331
Jeff Browne95c3cd2014-05-02 16:59:26 -0700332 boolean mInteractive;
333 StopwatchTimer mInteractiveTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700334
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700335 boolean mPowerSaveModeEnabled;
336 StopwatchTimer mPowerSaveModeEnabledTimer;
337
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700338 boolean mDeviceIdling;
339 StopwatchTimer mDeviceIdlingTimer;
340
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700341 boolean mDeviceLightIdling;
342 StopwatchTimer mDeviceLightIdlingTimer;
343
344 int mDeviceIdleMode;
345 long mLastIdleTimeStart;
346 long mLongestLightIdleTime;
347 long mLongestFullIdleTime;
348 StopwatchTimer mDeviceIdleModeLightTimer;
349 StopwatchTimer mDeviceIdleModeFullTimer;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700352 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700353
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700354 int mAudioOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700355 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700356
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700357 int mVideoOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700358 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700359
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700360 int mFlashlightOnNesting;
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700361 StopwatchTimer mFlashlightOnTimer;
362
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700363 int mCameraOnNesting;
364 StopwatchTimer mCameraOnTimer;
365
Dianne Hackborn627bba72009-03-24 22:32:56 -0700366 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800367 int mPhoneSignalStrengthBinRaw = -1;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700368 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800369 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700370
371 StopwatchTimer mPhoneSignalScanningTimer;
372
Dianne Hackborn627bba72009-03-24 22:32:56 -0700373 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700374 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700375 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700376
Dianne Hackborn57ed6a62013-12-09 18:15:56 -0800377 final LongSamplingCounter[] mNetworkByteActivityCounters =
378 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
379 final LongSamplingCounter[] mNetworkPacketActivityCounters =
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700380 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
381
Adam Lesinski33dac552015-03-09 15:24:48 -0700382 final LongSamplingCounter[] mBluetoothActivityCounters =
383 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
384
385 final LongSamplingCounter[] mWifiActivityCounters =
386 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
387
The Android Open Source Project10592532009-03-18 17:39:46 -0700388 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700389 StopwatchTimer mWifiOnTimer;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700390
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700391 boolean mGlobalWifiRunning;
392 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700393
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800394 int mWifiState = -1;
395 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
396
Dianne Hackborn3251b902014-06-20 14:40:53 -0700397 int mWifiSupplState = -1;
398 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES];
399
400 int mWifiSignalStrengthBin = -1;
401 final StopwatchTimer[] mWifiSignalStrengthsTimer =
402 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS];
403
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700404 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackbornf7097a52014-05-13 09:56:14 -0700405 long mMobileRadioActiveStartTime;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800406 StopwatchTimer mMobileRadioActiveTimer;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800407 StopwatchTimer mMobileRadioActivePerAppTimer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700408 LongSamplingCounter mMobileRadioActiveAdjustedTime;
Dianne Hackbornd45665b2014-02-26 12:35:32 -0800409 LongSamplingCounter mMobileRadioActiveUnknownTime;
410 LongSamplingCounter mMobileRadioActiveUnknownCount;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800411
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700412 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 /**
415 * These provide time bases that discount the time the device is plugged
416 * in to power.
417 */
418 boolean mOnBattery;
419 boolean mOnBatteryInternal;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700420
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700421 /**
422 * External reporting of whether the device is actually charging.
423 */
424 boolean mCharging = true;
425 int mLastChargingStateLevel;
426
The Android Open Source Project10592532009-03-18 17:39:46 -0700427 /*
428 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
429 */
Evan Millar633a1742009-04-02 16:36:33 -0700430 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700431 int mDischargeUnplugLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700432 int mDischargePlugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700433 int mDischargeCurrentLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700434 int mCurrentBatteryLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700435 int mLowDischargeAmountSinceCharge;
436 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800437 int mDischargeScreenOnUnplugLevel;
438 int mDischargeScreenOffUnplugLevel;
439 int mDischargeAmountScreenOn;
440 int mDischargeAmountScreenOnSinceCharge;
441 int mDischargeAmountScreenOff;
442 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700443
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700444 static final int MAX_LEVEL_STEPS = 200;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700445
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700446 int mInitStepMode = 0;
447 int mCurStepMode = 0;
448 int mModStepMode = 0;
449
Dianne Hackborn260c5022014-04-29 11:23:16 -0700450 int mLastDischargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700451 int mMinDischargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800452 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
453 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700454 ArrayList<PackageChange> mDailyPackageChanges;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700455
456 int mLastChargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700457 int mMaxChargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800458 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
459 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
460
461 static final int MAX_DAILY_ITEMS = 10;
462
463 long mDailyStartTime = 0;
464 long mNextMinDailyDeadline = 0;
465 long mNextMaxDailyDeadline = 0;
466
467 final ArrayList<DailyItem> mDailyItems = new ArrayList<>();
Dianne Hackborn260c5022014-04-29 11:23:16 -0700468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700470
Amith Yamasanif37447b2009-10-08 18:28:01 -0700471 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800472 private int mPhoneServiceStateRaw = -1;
473 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700474
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800475 private int mNumConnectivityChange;
476 private int mLoadedNumConnectivityChange;
477 private int mUnpluggedNumConnectivityChange;
478
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700479 private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
480
Adam Lesinskie08af192015-03-25 16:42:59 -0700481 private PowerProfile mPowerProfile;
Adam Lesinski17390762015-04-10 13:17:47 -0700482 private boolean mHasWifiEnergyReporting = false;
483 private boolean mHasBluetoothEnergyReporting = false;
Adam Lesinskie08af192015-03-25 16:42:59 -0700484
Evan Millarc64edde2009-04-18 12:26:32 -0700485 /*
486 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
487 */
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700488 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700489
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700490 public Map<String, ? extends Timer> getKernelWakelockStats() {
Evan Millarc64edde2009-04-18 12:26:32 -0700491 return mKernelWakelockStats;
492 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700493
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700494 String mLastWakeupReason = null;
495 long mLastWakeupUptimeMs = 0;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700496 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700497
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700498 public Map<String, ? extends Timer> getWakeupReasonStats() {
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700499 return mWakeupReasonStats;
500 }
501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700503 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700504 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800505 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700506 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700507 mExternalSync = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700508 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 }
510
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800511 public static interface TimeBaseObs {
512 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
513 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
514 }
515
516 static class TimeBase {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700517 private final ArrayList<TimeBaseObs> mObservers = new ArrayList<>();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800518
519 private long mUptime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800520 private long mRealtime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800521
522 private boolean mRunning;
523
524 private long mPastUptime;
525 private long mUptimeStart;
526 private long mPastRealtime;
527 private long mRealtimeStart;
528 private long mUnpluggedUptime;
529 private long mUnpluggedRealtime;
530
531 public void dump(PrintWriter pw, String prefix) {
532 StringBuilder sb = new StringBuilder(128);
533 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
534 sb.setLength(0);
535 sb.append(prefix);
536 sb.append("mUptime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700537 formatTimeMs(sb, mUptime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800538 pw.println(sb.toString());
539 sb.setLength(0);
540 sb.append(prefix);
541 sb.append("mRealtime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700542 formatTimeMs(sb, mRealtime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800543 pw.println(sb.toString());
544 sb.setLength(0);
545 sb.append(prefix);
546 sb.append("mPastUptime=");
547 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
548 formatTimeMs(sb, mUptimeStart / 1000);
549 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
550 pw.println(sb.toString());
551 sb.setLength(0);
552 sb.append(prefix);
553 sb.append("mPastRealtime=");
554 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
555 formatTimeMs(sb, mRealtimeStart / 1000);
556 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
557 pw.println(sb.toString());
558 }
559
560 public void add(TimeBaseObs observer) {
561 mObservers.add(observer);
562 }
563
564 public void remove(TimeBaseObs observer) {
565 if (!mObservers.remove(observer)) {
566 Slog.wtf(TAG, "Removed unknown observer: " + observer);
567 }
568 }
569
570 public void init(long uptime, long realtime) {
571 mRealtime = 0;
572 mUptime = 0;
573 mPastUptime = 0;
574 mPastRealtime = 0;
575 mUptimeStart = uptime;
576 mRealtimeStart = realtime;
577 mUnpluggedUptime = getUptime(mUptimeStart);
578 mUnpluggedRealtime = getRealtime(mRealtimeStart);
579 }
580
581 public void reset(long uptime, long realtime) {
582 if (!mRunning) {
583 mPastUptime = 0;
584 mPastRealtime = 0;
585 } else {
586 mUptimeStart = uptime;
587 mRealtimeStart = realtime;
588 mUnpluggedUptime = getUptime(uptime);
589 mUnpluggedRealtime = getRealtime(realtime);
590 }
591 }
592
593 public long computeUptime(long curTime, int which) {
594 switch (which) {
595 case STATS_SINCE_CHARGED:
596 return mUptime + getUptime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800597 case STATS_CURRENT:
598 return getUptime(curTime);
599 case STATS_SINCE_UNPLUGGED:
600 return getUptime(curTime) - mUnpluggedUptime;
601 }
602 return 0;
603 }
604
605 public long computeRealtime(long curTime, int which) {
606 switch (which) {
607 case STATS_SINCE_CHARGED:
608 return mRealtime + getRealtime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800609 case STATS_CURRENT:
610 return getRealtime(curTime);
611 case STATS_SINCE_UNPLUGGED:
612 return getRealtime(curTime) - mUnpluggedRealtime;
613 }
614 return 0;
615 }
616
617 public long getUptime(long curTime) {
618 long time = mPastUptime;
619 if (mRunning) {
620 time += curTime - mUptimeStart;
621 }
622 return time;
623 }
624
625 public long getRealtime(long curTime) {
626 long time = mPastRealtime;
627 if (mRunning) {
628 time += curTime - mRealtimeStart;
629 }
630 return time;
631 }
632
633 public long getUptimeStart() {
634 return mUptimeStart;
635 }
636
637 public long getRealtimeStart() {
638 return mRealtimeStart;
639 }
640
641 public boolean isRunning() {
642 return mRunning;
643 }
644
645 public boolean setRunning(boolean running, long uptime, long realtime) {
646 if (mRunning != running) {
647 mRunning = running;
648 if (running) {
649 mUptimeStart = uptime;
650 mRealtimeStart = realtime;
651 long batteryUptime = mUnpluggedUptime = getUptime(uptime);
652 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
653
654 for (int i = mObservers.size() - 1; i >= 0; i--) {
655 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
656 }
657 } else {
658 mPastUptime += uptime - mUptimeStart;
659 mPastRealtime += realtime - mRealtimeStart;
660
661 long batteryUptime = getUptime(uptime);
662 long batteryRealtime = getRealtime(realtime);
663
664 for (int i = mObservers.size() - 1; i >= 0; i--) {
665 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
666 }
667 }
668 return true;
669 }
670 return false;
671 }
672
673 public void readSummaryFromParcel(Parcel in) {
674 mUptime = in.readLong();
675 mRealtime = in.readLong();
676 }
677
678 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
679 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
680 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
681 }
682
683 public void readFromParcel(Parcel in) {
684 mRunning = false;
685 mUptime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800686 mPastUptime = in.readLong();
687 mUptimeStart = in.readLong();
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700688 mRealtime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800689 mPastRealtime = in.readLong();
690 mRealtimeStart = in.readLong();
691 mUnpluggedUptime = in.readLong();
692 mUnpluggedRealtime = in.readLong();
693 }
694
695 public void writeToParcel(Parcel out, long uptime, long realtime) {
696 final long runningUptime = getUptime(uptime);
697 final long runningRealtime = getRealtime(realtime);
698 out.writeLong(mUptime);
699 out.writeLong(runningUptime);
700 out.writeLong(mUptimeStart);
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700701 out.writeLong(mRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800702 out.writeLong(runningRealtime);
703 out.writeLong(mRealtimeStart);
704 out.writeLong(mUnpluggedUptime);
705 out.writeLong(mUnpluggedRealtime);
706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800709 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700710 * State for keeping track of counting information.
711 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800712 public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
Christopher Tate4cee7252010-03-19 14:50:40 -0700713 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800714 final TimeBase mTimeBase;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700715 int mLoadedCount;
716 int mLastCount;
717 int mUnpluggedCount;
718 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700719
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800720 Counter(TimeBase timeBase, Parcel in) {
721 mTimeBase = timeBase;
Christopher Tate4cee7252010-03-19 14:50:40 -0700722 mPluggedCount = in.readInt();
723 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700724 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700725 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700726 mUnpluggedCount = in.readInt();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800727 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700728 }
729
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800730 Counter(TimeBase timeBase) {
731 mTimeBase = timeBase;
732 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700733 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700734
Dianne Hackborn617f8772009-03-31 15:04:46 -0700735 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700736 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700737 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700738 out.writeInt(mUnpluggedCount);
739 }
740
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800741 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700742 mUnpluggedCount = mPluggedCount;
743 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700744 }
745
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800746 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700747 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700748 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700749
Dianne Hackborn617f8772009-03-31 15:04:46 -0700750 /**
751 * Writes a possibly null Counter to a Parcel.
752 *
753 * @param out the Parcel to be written to.
754 * @param counter a Counter, or null.
755 */
756 public static void writeCounterToParcel(Parcel out, Counter counter) {
757 if (counter == null) {
758 out.writeInt(0); // indicates null
759 return;
760 }
761 out.writeInt(1); // indicates non-null
762
763 counter.writeToParcel(out);
764 }
765
766 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700767 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700768 int val = mCount.get();
769 if (which == STATS_SINCE_UNPLUGGED) {
770 val -= mUnpluggedCount;
771 } else if (which != STATS_SINCE_CHARGED) {
772 val -= mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700773 }
774
775 return val;
776 }
777
778 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700779 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700780 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
781 + " mUnpluggedCount=" + mUnpluggedCount
782 + " mPluggedCount=" + mPluggedCount);
783 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700784
Christopher Tate4cee7252010-03-19 14:50:40 -0700785 void stepAtomic() {
786 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700787 }
788
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700789 /**
790 * Clear state of this counter.
791 */
792 void reset(boolean detachIfReset) {
793 mCount.set(0);
794 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
795 if (detachIfReset) {
796 detach();
797 }
798 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700799
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700800 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800801 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700802 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700803
Dianne Hackborn617f8772009-03-31 15:04:46 -0700804 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700805 int count = mCount.get();
806 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700807 }
808
809 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700810 mLoadedCount = in.readInt();
811 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700812 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700813 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700814 }
815 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700816
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700817 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800818 final TimeBase mTimeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700819 long mCount;
820 long mLoadedCount;
821 long mLastCount;
822 long mUnpluggedCount;
823 long mPluggedCount;
824
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800825 LongSamplingCounter(TimeBase timeBase, Parcel in) {
826 mTimeBase = timeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700827 mPluggedCount = in.readLong();
828 mCount = mPluggedCount;
829 mLoadedCount = in.readLong();
830 mLastCount = 0;
831 mUnpluggedCount = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800832 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700833 }
834
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800835 LongSamplingCounter(TimeBase timeBase) {
836 mTimeBase = timeBase;
837 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700838 }
839
840 public void writeToParcel(Parcel out) {
841 out.writeLong(mCount);
842 out.writeLong(mLoadedCount);
843 out.writeLong(mUnpluggedCount);
844 }
845
846 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800847 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700848 mUnpluggedCount = mPluggedCount;
849 mCount = mPluggedCount;
850 }
851
852 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800853 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700854 mPluggedCount = mCount;
855 }
856
857 public long getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700858 long val = mCount;
859 if (which == STATS_SINCE_UNPLUGGED) {
860 val -= mUnpluggedCount;
861 } else if (which != STATS_SINCE_CHARGED) {
862 val -= mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700863 }
864
865 return val;
866 }
867
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700868 @Override
869 public void logState(Printer pw, String prefix) {
870 pw.println(prefix + "mCount=" + mCount
871 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
872 + " mUnpluggedCount=" + mUnpluggedCount
873 + " mPluggedCount=" + mPluggedCount);
874 }
875
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700876 void addCountLocked(long count) {
877 mCount += count;
878 }
879
880 /**
881 * Clear state of this counter.
882 */
883 void reset(boolean detachIfReset) {
884 mCount = 0;
885 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
886 if (detachIfReset) {
887 detach();
888 }
889 }
890
891 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800892 mTimeBase.remove(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700893 }
894
895 void writeSummaryFromParcelLocked(Parcel out) {
896 out.writeLong(mCount);
897 }
898
899 void readSummaryFromParcelLocked(Parcel in) {
900 mLoadedCount = in.readLong();
901 mCount = mLoadedCount;
902 mLastCount = 0;
903 mUnpluggedCount = mPluggedCount = mLoadedCount;
904 }
905 }
906
Dianne Hackborn617f8772009-03-31 15:04:46 -0700907 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 * State for keeping track of timing information.
909 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800910 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 final int mType;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800912 final TimeBase mTimeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 int mCount;
915 int mLoadedCount;
916 int mLastCount;
917 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 // Times are in microseconds for better accuracy when dividing by the
920 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 /**
923 * The total time we have accumulated since the start of the original
924 * boot, to the last time something interesting happened in the
925 * current run.
926 */
927 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 /**
930 * The total time we loaded for the previous runs. Subtract this from
931 * mTotalTime to find the time for the current run of the system.
932 */
933 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 /**
936 * The run time of the last run of the system, as loaded from the
937 * saved data.
938 */
939 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 /**
942 * The value of mTotalTime when unplug() was last called. Subtract
943 * this from mTotalTime to find the time since the last unplug from
944 * power.
945 */
946 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700947
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700948 /**
Adam Lesinskie08af192015-03-25 16:42:59 -0700949 * The total time this timer has been running until the latest mark has been set.
950 * Subtract this from mTotalTime to get the time spent running since the mark was set.
951 */
952 long mTimeBeforeMark;
953
954 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700955 * Constructs from a parcel.
956 * @param type
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800957 * @param timeBase
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700958 * @param in
959 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800960 Timer(int type, TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800962 mTimeBase = timeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 mCount = in.readInt();
965 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700966 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 mUnpluggedCount = in.readInt();
968 mTotalTime = in.readLong();
969 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700970 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 mUnpluggedTime = in.readLong();
Adam Lesinskie08af192015-03-25 16:42:59 -0700972 mTimeBeforeMark = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800973 timeBase.add(this);
Dianne Hackborn29325132014-05-21 15:01:03 -0700974 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 }
976
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800977 Timer(int type, TimeBase timeBase) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800979 mTimeBase = timeBase;
980 timeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 }
Evan Millarc64edde2009-04-18 12:26:32 -0700982
983 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700984
Evan Millarc64edde2009-04-18 12:26:32 -0700985 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700986
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700987 /**
988 * Clear state of this timer. Returns true if the timer is inactive
989 * so can be completely dropped.
990 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800991 boolean reset(boolean detachIfReset) {
Adam Lesinskie08af192015-03-25 16:42:59 -0700992 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700993 mCount = mLoadedCount = mLastCount = 0;
994 if (detachIfReset) {
995 detach();
996 }
997 return true;
998 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700999
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001000 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001001 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001002 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001003
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001004 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
Dianne Hackborn29325132014-05-21 15:01:03 -07001005 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
1006 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 out.writeInt(mCount);
1008 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 out.writeInt(mUnpluggedCount);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001010 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 out.writeLong(mUnpluggedTime);
Adam Lesinskie08af192015-03-25 16:42:59 -07001013 out.writeLong(mTimeBeforeMark);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 }
1015
Adam Lesinskie08af192015-03-25 16:42:59 -07001016 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001017 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001019 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 + " old mUnpluggedTime=" + mUnpluggedTime
1021 + " old mUnpluggedCount=" + mUnpluggedCount);
1022 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001023 mUnpluggedTime = computeRunTimeLocked(baseRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 mUnpluggedCount = mCount;
1025 if (DEBUG && mType < 0) {
1026 Log.v(TAG, "unplug #" + mType
1027 + ": new mUnpluggedTime=" + mUnpluggedTime
1028 + " new mUnpluggedCount=" + mUnpluggedCount);
1029 }
1030 }
1031
Adam Lesinskie08af192015-03-25 16:42:59 -07001032 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001033 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001034 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001035 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
Evan Millarc64edde2009-04-18 12:26:32 -07001036 + " old mTotalTime=" + mTotalTime);
1037 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001038 mTotalTime = computeRunTimeLocked(baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001039 mCount = computeCurrentCountLocked();
1040 if (DEBUG && mType < 0) {
1041 Log.v(TAG, "plug #" + mType
1042 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043 }
1044 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 /**
1047 * Writes a possibly null Timer to a Parcel.
1048 *
1049 * @param out the Parcel to be written to.
1050 * @param timer a Timer, or null.
1051 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001052 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 if (timer == null) {
1054 out.writeInt(0); // indicates null
1055 return;
1056 }
1057 out.writeInt(1); // indicates non-null
1058
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001059 timer.writeToParcel(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 }
1061
1062 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001063 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001064 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1065 if (which == STATS_SINCE_UNPLUGGED) {
1066 val -= mUnpluggedTime;
1067 } else if (which != STATS_SINCE_CHARGED) {
1068 val -= mLoadedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 }
1070
1071 return val;
1072 }
1073
1074 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001075 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001076 int val = computeCurrentCountLocked();
1077 if (which == STATS_SINCE_UNPLUGGED) {
1078 val -= mUnpluggedCount;
1079 } else if (which != STATS_SINCE_CHARGED) {
1080 val -= mLoadedCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 }
1082
1083 return val;
1084 }
1085
Adam Lesinskie08af192015-03-25 16:42:59 -07001086 @Override
1087 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) {
1088 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1089 return val - mTimeBeforeMark;
1090 }
1091
1092 @Override
Dianne Hackborn627bba72009-03-24 22:32:56 -07001093 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001094 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
1096 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001097 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001099 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001101 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001102
1103
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001104 void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
1105 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1106 out.writeLong(runTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001107 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -07001108 }
1109
1110 void readSummaryFromParcelLocked(Parcel in) {
1111 // Multiply by 1000 for backwards compatibility
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001112 mTotalTime = mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001113 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001114 mUnpluggedTime = mTotalTime;
1115 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001116 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001117 mUnpluggedCount = mCount;
Adam Lesinskie08af192015-03-25 16:42:59 -07001118
1119 // When reading the summary, we set the mark to be the latest information.
1120 mTimeBeforeMark = mTotalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001121 }
1122 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001123
Evan Millarc64edde2009-04-18 12:26:32 -07001124 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001125
Evan Millarc64edde2009-04-18 12:26:32 -07001126 /**
1127 * The most recent reported count from /proc/wakelocks.
1128 */
1129 int mCurrentReportedCount;
1130
1131 /**
1132 * The reported count from /proc/wakelocks when unplug() was last
1133 * called.
1134 */
1135 int mUnpluggedReportedCount;
1136
1137 /**
1138 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001139 */
Evan Millarc64edde2009-04-18 12:26:32 -07001140 long mCurrentReportedTotalTime;
1141
1142
1143 /**
1144 * The reported total_time from /proc/wakelocks when unplug() was last
1145 * called.
1146 */
1147 long mUnpluggedReportedTotalTime;
1148
1149 /**
1150 * Whether we are currently in a discharge cycle.
1151 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001152 boolean mTimeBaseRunning;
Evan Millarc64edde2009-04-18 12:26:32 -07001153
1154 /**
1155 * Whether we are currently recording reported values.
1156 */
1157 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001158
Evan Millarc64edde2009-04-18 12:26:32 -07001159 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001160 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -07001161 */
1162 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001163
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001164 SamplingTimer(TimeBase timeBase, Parcel in) {
1165 super(0, timeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07001166 mCurrentReportedCount = in.readInt();
1167 mUnpluggedReportedCount = in.readInt();
1168 mCurrentReportedTotalTime = in.readLong();
1169 mUnpluggedReportedTotalTime = in.readLong();
1170 mTrackingReportedValues = in.readInt() == 1;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001171 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001172 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001173
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001174 SamplingTimer(TimeBase timeBase, boolean trackReportedValues) {
1175 super(0, timeBase);
Evan Millarc64edde2009-04-18 12:26:32 -07001176 mTrackingReportedValues = trackReportedValues;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001177 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001178 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001179
Evan Millarc64edde2009-04-18 12:26:32 -07001180 public void setStale() {
1181 mTrackingReportedValues = false;
1182 mUnpluggedReportedTotalTime = 0;
1183 mUnpluggedReportedCount = 0;
1184 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001185
Evan Millarc64edde2009-04-18 12:26:32 -07001186 public void setUpdateVersion(int version) {
1187 mUpdateVersion = version;
1188 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001189
Evan Millarc64edde2009-04-18 12:26:32 -07001190 public int getUpdateVersion() {
1191 return mUpdateVersion;
1192 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001193
Evan Millarc64edde2009-04-18 12:26:32 -07001194 public void updateCurrentReportedCount(int count) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001195 if (mTimeBaseRunning && mUnpluggedReportedCount == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001196 // Updating the reported value for the first time.
1197 mUnpluggedReportedCount = count;
1198 // If we are receiving an update update mTrackingReportedValues;
1199 mTrackingReportedValues = true;
1200 }
1201 mCurrentReportedCount = count;
1202 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001203
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001204 public void addCurrentReportedCount(int delta) {
1205 updateCurrentReportedCount(mCurrentReportedCount + delta);
1206 }
1207
Evan Millarc64edde2009-04-18 12:26:32 -07001208 public void updateCurrentReportedTotalTime(long totalTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001209 if (mTimeBaseRunning && mUnpluggedReportedTotalTime == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001210 // Updating the reported value for the first time.
1211 mUnpluggedReportedTotalTime = totalTime;
1212 // If we are receiving an update update mTrackingReportedValues;
1213 mTrackingReportedValues = true;
1214 }
1215 mCurrentReportedTotalTime = totalTime;
1216 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001217
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001218 public void addCurrentReportedTotalTime(long delta) {
1219 updateCurrentReportedTotalTime(mCurrentReportedTotalTime + delta);
1220 }
1221
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001222 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1223 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001224 if (mTrackingReportedValues) {
1225 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
1226 mUnpluggedReportedCount = mCurrentReportedCount;
1227 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001228 mTimeBaseRunning = true;
Evan Millarc64edde2009-04-18 12:26:32 -07001229 }
1230
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001231 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1232 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1233 mTimeBaseRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001234 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001235
Evan Millarc64edde2009-04-18 12:26:32 -07001236 public void logState(Printer pw, String prefix) {
1237 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001238 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -07001239 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
1240 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
1241 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
1242 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001243
Evan Millarc64edde2009-04-18 12:26:32 -07001244 protected long computeRunTimeLocked(long curBatteryRealtime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001245 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001246 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
1247 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001248
Evan Millarc64edde2009-04-18 12:26:32 -07001249 protected int computeCurrentCountLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001250 return mCount + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001251 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
1252 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001253
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001254 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1255 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001256 out.writeInt(mCurrentReportedCount);
1257 out.writeInt(mUnpluggedReportedCount);
1258 out.writeLong(mCurrentReportedTotalTime);
1259 out.writeLong(mUnpluggedReportedTotalTime);
1260 out.writeInt(mTrackingReportedValues ? 1 : 0);
1261 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001262
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001263 boolean reset(boolean detachIfReset) {
1264 super.reset(detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001265 setStale();
1266 return true;
1267 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001268
Evan Millarc64edde2009-04-18 12:26:32 -07001269 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
1270 super.writeSummaryFromParcelLocked(out, batteryRealtime);
1271 out.writeLong(mCurrentReportedTotalTime);
1272 out.writeInt(mCurrentReportedCount);
1273 out.writeInt(mTrackingReportedValues ? 1 : 0);
1274 }
1275
1276 void readSummaryFromParcelLocked(Parcel in) {
1277 super.readSummaryFromParcelLocked(in);
1278 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
1279 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
1280 mTrackingReportedValues = in.readInt() == 1;
1281 }
1282 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001283
Evan Millarc64edde2009-04-18 12:26:32 -07001284 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001285 * A timer that increments in batches. It does not run for durations, but just jumps
1286 * for a pre-determined amount.
1287 */
1288 public static final class BatchTimer extends Timer {
1289 final Uid mUid;
1290
1291 /**
1292 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
1293 */
1294 long mLastAddedTime;
1295
1296 /**
1297 * The last duration that we added to the timer. This is in microseconds.
1298 */
1299 long mLastAddedDuration;
1300
1301 /**
1302 * Whether we are currently in a discharge cycle.
1303 */
1304 boolean mInDischarge;
1305
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001306 BatchTimer(Uid uid, int type, TimeBase timeBase, Parcel in) {
1307 super(type, timeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001308 mUid = uid;
1309 mLastAddedTime = in.readLong();
1310 mLastAddedDuration = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001311 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001312 }
1313
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001314 BatchTimer(Uid uid, int type, TimeBase timeBase) {
1315 super(type, timeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001316 mUid = uid;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001317 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001318 }
1319
1320 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001321 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1322 super.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001323 out.writeLong(mLastAddedTime);
1324 out.writeLong(mLastAddedDuration);
1325 }
1326
1327 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001328 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001329 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
1330 mInDischarge = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001331 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001332 }
1333
1334 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001335 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001336 recomputeLastDuration(elapsedRealtime, false);
1337 mInDischarge = true;
1338 // If we are still within the last added duration, then re-added whatever remains.
1339 if (mLastAddedTime == elapsedRealtime) {
1340 mTotalTime += mLastAddedDuration;
1341 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001342 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001343 }
1344
1345 @Override
1346 public void logState(Printer pw, String prefix) {
1347 super.logState(pw, prefix);
1348 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
1349 + " mLastAddedDuration=" + mLastAddedDuration);
1350 }
1351
1352 private long computeOverage(long curTime) {
1353 if (mLastAddedTime > 0) {
1354 return mLastTime + mLastAddedDuration - curTime;
1355 }
1356 return 0;
1357 }
1358
1359 private void recomputeLastDuration(long curTime, boolean abort) {
1360 final long overage = computeOverage(curTime);
1361 if (overage > 0) {
1362 // Aborting before the duration ran out -- roll back the remaining
1363 // duration. Only do this if currently discharging; otherwise we didn't
1364 // actually add the time.
1365 if (mInDischarge) {
1366 mTotalTime -= overage;
1367 }
1368 if (abort) {
1369 mLastAddedTime = 0;
1370 } else {
1371 mLastAddedTime = curTime;
1372 mLastAddedDuration -= overage;
1373 }
1374 }
1375 }
1376
1377 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
1378 final long now = SystemClock.elapsedRealtime() * 1000;
1379 recomputeLastDuration(now, true);
1380 mLastAddedTime = now;
1381 mLastAddedDuration = durationMillis * 1000;
1382 if (mInDischarge) {
1383 mTotalTime += mLastAddedDuration;
1384 mCount++;
1385 }
1386 }
1387
1388 public void abortLastDuration(BatteryStatsImpl stats) {
1389 final long now = SystemClock.elapsedRealtime() * 1000;
1390 recomputeLastDuration(now, true);
1391 }
1392
1393 @Override
1394 protected int computeCurrentCountLocked() {
1395 return mCount;
1396 }
1397
1398 @Override
1399 protected long computeRunTimeLocked(long curBatteryRealtime) {
1400 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000);
1401 if (overage > 0) {
1402 return mTotalTime = overage;
1403 }
1404 return mTotalTime;
1405 }
1406
1407 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001408 boolean reset(boolean detachIfReset) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001409 final long now = SystemClock.elapsedRealtime() * 1000;
1410 recomputeLastDuration(now, true);
1411 boolean stillActive = mLastAddedTime == now;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001412 super.reset(!stillActive && detachIfReset);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001413 return !stillActive;
1414 }
1415 }
1416
1417 /**
Evan Millarc64edde2009-04-18 12:26:32 -07001418 * State for keeping track of timing information.
1419 */
1420 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001421 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07001422 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001423
Evan Millarc64edde2009-04-18 12:26:32 -07001424 int mNesting;
1425
Evan Millarc64edde2009-04-18 12:26:32 -07001426 /**
1427 * The last time at which we updated the timer. If mNesting is > 0,
1428 * subtract this from the current battery time to find the amount of
1429 * time we have been running since we last computed an update.
1430 */
1431 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001432
Evan Millarc64edde2009-04-18 12:26:32 -07001433 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001434 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -07001435 * was actually held for an interesting duration.
1436 */
1437 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001438
Amith Yamasanif37447b2009-10-08 18:28:01 -07001439 long mTimeout;
1440
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001441 /**
1442 * For partial wake locks, keep track of whether we are in the list
1443 * to consume CPU cycles.
1444 */
1445 boolean mInList;
1446
1447 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001448 TimeBase timeBase, Parcel in) {
1449 super(type, timeBase, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001450 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001451 mTimerPool = timerPool;
1452 mUpdateTime = in.readLong();
1453 }
1454
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001455 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001456 TimeBase timeBase) {
1457 super(type, timeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001458 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001459 mTimerPool = timerPool;
1460 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001461
Amith Yamasanif37447b2009-10-08 18:28:01 -07001462 void setTimeout(long timeout) {
1463 mTimeout = timeout;
1464 }
1465
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001466 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1467 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001468 out.writeLong(mUpdateTime);
1469 }
1470
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001471 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001472 if (mNesting > 0) {
1473 if (DEBUG && mType < 0) {
1474 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
1475 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001476 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1477 mUpdateTime = baseRealtime;
Evan Millarc64edde2009-04-18 12:26:32 -07001478 if (DEBUG && mType < 0) {
1479 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
1480 }
1481 }
1482 }
1483
1484 public void logState(Printer pw, String prefix) {
1485 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001486 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 + " mAcquireTime=" + mAcquireTime);
1488 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001489
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001490 void startRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 if (mNesting++ == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001492 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001493 mUpdateTime = batteryRealtime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 if (mTimerPool != null) {
1495 // Accumulate time to all currently active timers before adding
1496 // this new one to the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001497 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 // Add this timer to the active pool
1499 mTimerPool.add(this);
1500 }
1501 // Increment the count
1502 mCount++;
1503 mAcquireTime = mTotalTime;
1504 if (DEBUG && mType < 0) {
1505 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
1506 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1507 + " mAcquireTime=" + mAcquireTime);
1508 }
1509 }
1510 }
1511
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001512 boolean isRunningLocked() {
1513 return mNesting > 0;
1514 }
1515
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001516 void stopRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 // Ignore attempt to stop a timer that isn't running
1518 if (mNesting == 0) {
1519 return;
1520 }
1521 if (--mNesting == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001522 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 if (mTimerPool != null) {
1524 // Accumulate time to all active counters, scaled by the total
1525 // active in the pool, before taking this one out of the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001526 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 // Remove this timer from the active pool
1528 mTimerPool.remove(this);
1529 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 mNesting = 1;
1531 mTotalTime = computeRunTimeLocked(batteryRealtime);
1532 mNesting = 0;
1533 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 if (DEBUG && mType < 0) {
1536 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
1537 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1538 + " mAcquireTime=" + mAcquireTime);
1539 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 if (mTotalTime == mAcquireTime) {
1542 // If there was no change in the time, then discard this
1543 // count. A somewhat cheezy strategy, but hey.
1544 mCount--;
1545 }
1546 }
1547 }
1548
Dianne Hackborn10eaa852014-07-22 22:54:55 -07001549 void stopAllRunningLocked(long elapsedRealtimeMs) {
1550 if (mNesting > 0) {
1551 mNesting = 1;
1552 stopRunningLocked(elapsedRealtimeMs);
1553 }
1554 }
1555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 // Update the total time for all other running Timers with the same type as this Timer
1557 // due to a change in timer count
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001558 private static long refreshTimersLocked(long batteryRealtime,
1559 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001560 long selfTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 final int N = pool.size();
1562 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07001563 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 long heldTime = batteryRealtime - t.mUpdateTime;
1565 if (heldTime > 0) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001566 final long myTime = heldTime / N;
1567 if (t == self) {
1568 selfTime = myTime;
1569 }
1570 t.mTotalTime += myTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 }
1572 t.mUpdateTime = batteryRealtime;
1573 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001574 return selfTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 }
1576
Evan Millarc64edde2009-04-18 12:26:32 -07001577 @Override
1578 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001579 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
1580 curBatteryRealtime = mUpdateTime + mTimeout;
1581 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 return mTotalTime + (mNesting > 0
1583 ? (curBatteryRealtime - mUpdateTime)
1584 / (mTimerPool != null ? mTimerPool.size() : 1)
1585 : 0);
1586 }
1587
Evan Millarc64edde2009-04-18 12:26:32 -07001588 @Override
1589 protected int computeCurrentCountLocked() {
1590 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 }
1592
Adam Lesinskie08af192015-03-25 16:42:59 -07001593 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001594 boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001595 boolean canDetach = mNesting <= 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001596 super.reset(canDetach && detachIfReset);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001597 if (mNesting > 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001598 mUpdateTime = mTimeBase.getRealtime(SystemClock.elapsedRealtime() * 1000);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001599 }
1600 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001601 return canDetach;
1602 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001603
Adam Lesinskie08af192015-03-25 16:42:59 -07001604 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001605 void detach() {
1606 super.detach();
1607 if (mTimerPool != null) {
1608 mTimerPool.remove(this);
1609 }
1610 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001611
Adam Lesinskie08af192015-03-25 16:42:59 -07001612 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001613 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001614 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001615 mNesting = 0;
1616 }
Adam Lesinskie08af192015-03-25 16:42:59 -07001617
1618 /**
1619 * Set the mark so that we can query later for the total time the timer has
1620 * accumulated since this point. The timer can be running or not.
1621 *
1622 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds.
1623 */
1624 public void setMark(long elapsedRealtimeMs) {
1625 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
1626 if (mNesting > 0) {
1627 // We are running.
1628 if (mTimerPool != null) {
1629 refreshTimersLocked(batteryRealtime, mTimerPool, this);
1630 } else {
1631 mTotalTime += batteryRealtime - mUpdateTime;
1632 mUpdateTime = batteryRealtime;
1633 }
1634 }
1635 mTimeBeforeMark = mTotalTime;
1636 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001638
Dianne Hackbornd953c532014-08-16 18:17:38 -07001639 public abstract class OverflowArrayMap<T> {
1640 private static final String OVERFLOW_NAME = "*overflow*";
1641
1642 final ArrayMap<String, T> mMap = new ArrayMap<>();
1643 T mCurOverflow;
1644 ArrayMap<String, MutableInt> mActiveOverflow;
1645
1646 public OverflowArrayMap() {
1647 }
1648
1649 public ArrayMap<String, T> getMap() {
1650 return mMap;
1651 }
1652
1653 public void clear() {
1654 mMap.clear();
1655 mCurOverflow = null;
1656 mActiveOverflow = null;
1657 }
1658
1659 public void add(String name, T obj) {
1660 mMap.put(name, obj);
1661 if (OVERFLOW_NAME.equals(name)) {
1662 mCurOverflow = obj;
1663 }
1664 }
1665
1666 public void cleanup() {
1667 if (mActiveOverflow != null) {
1668 if (mActiveOverflow.size() == 0) {
1669 mActiveOverflow = null;
1670 }
1671 }
1672 if (mActiveOverflow == null) {
1673 // There is no currently active overflow, so we should no longer have
1674 // an overflow entry.
1675 if (mMap.containsKey(OVERFLOW_NAME)) {
1676 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry "
1677 + mMap.get(OVERFLOW_NAME));
1678 mMap.remove(OVERFLOW_NAME);
1679 }
1680 mCurOverflow = null;
1681 } else {
1682 // There is currently active overflow, so we should still have an overflow entry.
1683 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) {
1684 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur="
1685 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME));
1686 }
1687 }
1688 }
1689
1690 public T startObject(String name) {
1691 T obj = mMap.get(name);
1692 if (obj != null) {
1693 return obj;
1694 }
1695
1696 // No object exists for the given name, but do we currently have it
1697 // running as part of the overflow?
1698 if (mActiveOverflow != null) {
1699 MutableInt over = mActiveOverflow.get(name);
1700 if (over != null) {
1701 // We are already actively counting this name in the overflow object.
1702 obj = mCurOverflow;
1703 if (obj == null) {
1704 // Shouldn't be here, but we'll try to recover.
1705 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow");
1706 obj = mCurOverflow = instantiateObject();
1707 mMap.put(OVERFLOW_NAME, obj);
1708 }
1709 over.value++;
1710 return obj;
1711 }
1712 }
1713
1714 // No object exists for given name nor in the overflow; we need to make
1715 // a new one.
1716 final int N = mMap.size();
1717 if (N >= MAX_WAKELOCKS_PER_UID) {
1718 // Went over the limit on number of objects to track; this one goes
1719 // in to the overflow.
1720 obj = mCurOverflow;
1721 if (obj == null) {
1722 // Need to start overflow now...
1723 obj = mCurOverflow = instantiateObject();
1724 mMap.put(OVERFLOW_NAME, obj);
1725 }
1726 if (mActiveOverflow == null) {
1727 mActiveOverflow = new ArrayMap<>();
1728 }
1729 mActiveOverflow.put(name, new MutableInt(1));
1730 return obj;
1731 }
1732
1733 // Normal case where we just need to make a new object.
1734 obj = instantiateObject();
1735 mMap.put(name, obj);
1736 return obj;
1737 }
1738
1739 public T stopObject(String name) {
1740 T obj = mMap.get(name);
1741 if (obj != null) {
1742 return obj;
1743 }
1744
1745 // No object exists for the given name, but do we currently have it
1746 // running as part of the overflow?
1747 if (mActiveOverflow != null) {
1748 MutableInt over = mActiveOverflow.get(name);
1749 if (over != null) {
1750 // We are already actively counting this name in the overflow object.
1751 obj = mCurOverflow;
1752 if (obj != null) {
1753 over.value--;
1754 if (over.value <= 0) {
1755 mActiveOverflow.remove(name);
1756 }
1757 return obj;
1758 }
1759 }
1760 }
1761
1762 // Huh, they are stopping an active operation but we can't find one!
1763 // That's not good.
1764 Slog.wtf(TAG, "Unable to find object for " + name + " mapsize="
1765 + mMap.size() + " activeoverflow=" + mActiveOverflow
1766 + " curoverflow=" + mCurOverflow);
1767 return null;
1768 }
1769
1770 public abstract T instantiateObject();
1771 }
1772
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001773 /*
1774 * Get the wakeup reason counter, and create a new one if one
1775 * doesn't already exist.
1776 */
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001777 public SamplingTimer getWakeupReasonTimerLocked(String name) {
1778 SamplingTimer timer = mWakeupReasonStats.get(name);
1779 if (timer == null) {
1780 timer = new SamplingTimer(mOnBatteryTimeBase, true);
1781 mWakeupReasonStats.put(name, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001782 }
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001783 return timer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001784 }
1785
Evan Millarc64edde2009-04-18 12:26:32 -07001786 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001787 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001788 * doesn't already exist.
1789 */
1790 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1791 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1792 if (kwlt == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001793 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, true /* track reported values */);
Evan Millarc64edde2009-04-18 12:26:32 -07001794 mKernelWakelockStats.put(name, kwlt);
1795 }
1796 return kwlt;
1797 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001798
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001799 private int writeHistoryTag(HistoryTag tag) {
1800 Integer idxObj = mHistoryTagPool.get(tag);
1801 int idx;
1802 if (idxObj != null) {
1803 idx = idxObj;
1804 } else {
1805 idx = mNextHistoryTagIdx;
1806 HistoryTag key = new HistoryTag();
1807 key.setTo(tag);
1808 tag.poolIdx = idx;
1809 mHistoryTagPool.put(key, idx);
1810 mNextHistoryTagIdx++;
1811 mNumHistoryTagChars += key.string.length() + 1;
1812 }
1813 return idx;
1814 }
1815
1816 private void readHistoryTag(int index, HistoryTag tag) {
1817 tag.string = mReadHistoryStrings[index];
1818 tag.uid = mReadHistoryUids[index];
1819 tag.poolIdx = index;
1820 }
1821
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001822 // Part of initial delta int that specifies the time delta.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001823 static final int DELTA_TIME_MASK = 0x7ffff;
1824 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
1825 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
1826 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001827 // Flag in delta int: a new battery level int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001828 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001829 // Flag in delta int: a new full state and battery status int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001830 static final int DELTA_STATE_FLAG = 0x00100000;
1831 // Flag in delta int: a new full state2 int follows.
1832 static final int DELTA_STATE2_FLAG = 0x00200000;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001833 // Flag in delta int: contains a wakelock or wakeReason tag.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001834 static final int DELTA_WAKELOCK_FLAG = 0x00400000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001835 // Flag in delta int: contains an event description.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001836 static final int DELTA_EVENT_FLAG = 0x00800000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001837 // These upper bits are the frequently changing state bits.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001838 static final int DELTA_STATE_MASK = 0xff000000;
1839
1840 // These are the pieces of battery state that are packed in to the upper bits of
1841 // the state int that have been packed in to the first delta int. They must fit
1842 // in DELTA_STATE_MASK.
1843 static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
1844 static final int STATE_BATTERY_STATUS_SHIFT = 29;
1845 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
1846 static final int STATE_BATTERY_HEALTH_SHIFT = 26;
1847 static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
1848 static final int STATE_BATTERY_PLUG_SHIFT = 24;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001849
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001850 // We use the low bit of the battery state int to indicate that we have full details
1851 // from a battery level change.
1852 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001;
1853
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001854 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001855 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001856 dest.writeInt(DELTA_TIME_ABS);
1857 cur.writeToParcel(dest, 0);
1858 return;
1859 }
1860
1861 final long deltaTime = cur.time - last.time;
1862 final int lastBatteryLevelInt = buildBatteryLevelInt(last);
1863 final int lastStateInt = buildStateInt(last);
1864
1865 int deltaTimeToken;
1866 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
1867 deltaTimeToken = DELTA_TIME_LONG;
1868 } else if (deltaTime >= DELTA_TIME_ABS) {
1869 deltaTimeToken = DELTA_TIME_INT;
1870 } else {
1871 deltaTimeToken = (int)deltaTime;
1872 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001873 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001874 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel
1875 ? BATTERY_DELTA_LEVEL_FLAG : 0;
1876 final boolean computeStepDetails = includeStepDetails != 0
1877 || mLastHistoryStepDetails == null;
1878 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001879 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
1880 if (batteryLevelIntChanged) {
1881 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
1882 }
1883 final int stateInt = buildStateInt(cur);
1884 final boolean stateIntChanged = stateInt != lastStateInt;
1885 if (stateIntChanged) {
1886 firstToken |= DELTA_STATE_FLAG;
1887 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001888 final boolean state2IntChanged = cur.states2 != last.states2;
1889 if (state2IntChanged) {
1890 firstToken |= DELTA_STATE2_FLAG;
1891 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001892 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001893 firstToken |= DELTA_WAKELOCK_FLAG;
1894 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001895 if (cur.eventCode != HistoryItem.EVENT_NONE) {
1896 firstToken |= DELTA_EVENT_FLAG;
1897 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001898 dest.writeInt(firstToken);
1899 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
1900 + " deltaTime=" + deltaTime);
1901
1902 if (deltaTimeToken >= DELTA_TIME_INT) {
1903 if (deltaTimeToken == DELTA_TIME_INT) {
1904 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
1905 dest.writeInt((int)deltaTime);
1906 } else {
1907 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
1908 dest.writeLong(deltaTime);
1909 }
1910 }
1911 if (batteryLevelIntChanged) {
1912 dest.writeInt(batteryLevelInt);
1913 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
1914 + Integer.toHexString(batteryLevelInt)
1915 + " batteryLevel=" + cur.batteryLevel
1916 + " batteryTemp=" + cur.batteryTemperature
1917 + " batteryVolt=" + (int)cur.batteryVoltage);
1918 }
1919 if (stateIntChanged) {
1920 dest.writeInt(stateInt);
1921 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
1922 + Integer.toHexString(stateInt)
1923 + " batteryStatus=" + cur.batteryStatus
1924 + " batteryHealth=" + cur.batteryHealth
1925 + " batteryPlugType=" + cur.batteryPlugType
1926 + " states=0x" + Integer.toHexString(cur.states));
1927 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001928 if (state2IntChanged) {
1929 dest.writeInt(cur.states2);
1930 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
1931 + Integer.toHexString(cur.states2));
1932 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001933 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
1934 int wakeLockIndex;
1935 int wakeReasonIndex;
1936 if (cur.wakelockTag != null) {
1937 wakeLockIndex = writeHistoryTag(cur.wakelockTag);
1938 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
1939 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
1940 } else {
1941 wakeLockIndex = 0xffff;
1942 }
1943 if (cur.wakeReasonTag != null) {
1944 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
1945 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
1946 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
1947 } else {
1948 wakeReasonIndex = 0xffff;
1949 }
1950 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001951 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001952 if (cur.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001953 int index = writeHistoryTag(cur.eventTag);
1954 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
Dianne Hackborn099bc622014-01-22 13:39:16 -08001955 dest.writeInt(codeAndIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001956 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
1957 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
1958 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001959 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001960 if (computeStepDetails) {
1961 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
1962 if (includeStepDetails != 0) {
1963 mCurHistoryStepDetails.writeToParcel(dest);
1964 }
1965 cur.stepDetails = mCurHistoryStepDetails;
1966 mLastHistoryStepDetails = mCurHistoryStepDetails;
1967 } else {
1968 cur.stepDetails = null;
1969 }
1970 if (mLastHistoryStepLevel < cur.batteryLevel) {
1971 mLastHistoryStepDetails = null;
1972 }
1973 mLastHistoryStepLevel = cur.batteryLevel;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001974 }
1975
1976 private int buildBatteryLevelInt(HistoryItem h) {
1977 return ((((int)h.batteryLevel)<<25)&0xfe000000)
Adam Lesinski3944c812015-11-13 15:54:59 -08001978 | ((((int)h.batteryTemperature)<<15)&0x01ff8000)
1979 | ((((int)h.batteryVoltage)<<1)&0x00007ffe);
1980 }
1981
1982 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) {
1983 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25);
1984 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15);
1985 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001986 }
1987
1988 private int buildStateInt(HistoryItem h) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001989 int plugType = 0;
1990 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
1991 plugType = 1;
1992 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
1993 plugType = 2;
1994 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
1995 plugType = 3;
1996 }
1997 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
1998 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
1999 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002000 | (h.states&(~DELTA_STATE_MASK));
2001 }
2002
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002003 private void computeHistoryStepDetails(final HistoryStepDetails out,
2004 final HistoryStepDetails last) {
2005 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out;
2006
2007 // Perform a CPU update right after we do this collection, so we have started
2008 // collecting good data for the next step.
2009 requestImmediateCpuUpdate();
2010
2011 if (last == null) {
2012 // We are not generating a delta, so all we need to do is reset the stats
2013 // we will later be doing a delta from.
2014 final int NU = mUidStats.size();
2015 for (int i=0; i<NU; i++) {
2016 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
2017 uid.mLastStepUserTime = uid.mCurStepUserTime;
2018 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
2019 }
2020 mLastStepCpuUserTime = mCurStepCpuUserTime;
2021 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
2022 mLastStepStatUserTime = mCurStepStatUserTime;
2023 mLastStepStatSystemTime = mCurStepStatSystemTime;
2024 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
2025 mLastStepStatIrqTime = mCurStepStatIrqTime;
2026 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
2027 mLastStepStatIdleTime = mCurStepStatIdleTime;
2028 tmp.clear();
2029 return;
2030 }
2031 if (DEBUG) {
2032 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys="
2033 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime
2034 + " irq=" + mLastStepStatIrqTime + " sirq="
2035 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime);
2036 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys="
2037 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime
2038 + " irq=" + mCurStepStatIrqTime + " sirq="
2039 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime);
2040 }
2041 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime);
2042 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime);
2043 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime);
2044 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime);
2045 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime);
2046 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime);
2047 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime);
2048 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime);
2049 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1;
2050 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0;
2051 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0;
2052 final int NU = mUidStats.size();
2053 for (int i=0; i<NU; i++) {
2054 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
2055 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime);
2056 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime);
2057 final int totalTime = totalUTime + totalSTime;
2058 uid.mLastStepUserTime = uid.mCurStepUserTime;
2059 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
2060 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) {
2061 continue;
2062 }
2063 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) {
2064 out.appCpuUid3 = uid.mUid;
2065 out.appCpuUTime3 = totalUTime;
2066 out.appCpuSTime3 = totalSTime;
2067 } else {
2068 out.appCpuUid3 = out.appCpuUid2;
2069 out.appCpuUTime3 = out.appCpuUTime2;
2070 out.appCpuSTime3 = out.appCpuSTime2;
2071 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) {
2072 out.appCpuUid2 = uid.mUid;
2073 out.appCpuUTime2 = totalUTime;
2074 out.appCpuSTime2 = totalSTime;
2075 } else {
2076 out.appCpuUid2 = out.appCpuUid1;
2077 out.appCpuUTime2 = out.appCpuUTime1;
2078 out.appCpuSTime2 = out.appCpuSTime1;
2079 out.appCpuUid1 = uid.mUid;
2080 out.appCpuUTime1 = totalUTime;
2081 out.appCpuSTime1 = totalSTime;
2082 }
2083 }
2084 }
2085 mLastStepCpuUserTime = mCurStepCpuUserTime;
2086 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
2087 mLastStepStatUserTime = mCurStepStatUserTime;
2088 mLastStepStatSystemTime = mCurStepStatSystemTime;
2089 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
2090 mLastStepStatIrqTime = mCurStepStatIrqTime;
2091 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
2092 mLastStepStatIdleTime = mCurStepStatIdleTime;
2093 }
2094
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002095 public void readHistoryDelta(Parcel src, HistoryItem cur) {
2096 int firstToken = src.readInt();
2097 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002098 cur.cmd = HistoryItem.CMD_UPDATE;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002099 cur.numReadInts = 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002100 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
2101 + " deltaTimeToken=" + deltaTimeToken);
2102
2103 if (deltaTimeToken < DELTA_TIME_ABS) {
2104 cur.time += deltaTimeToken;
2105 } else if (deltaTimeToken == DELTA_TIME_ABS) {
2106 cur.time = src.readLong();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002107 cur.numReadInts += 2;
2108 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002109 cur.readFromParcel(src);
2110 return;
2111 } else if (deltaTimeToken == DELTA_TIME_INT) {
2112 int delta = src.readInt();
2113 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002114 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002115 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
2116 } else {
2117 long delta = src.readLong();
2118 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
2119 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002120 cur.numReadInts += 2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002121 }
2122
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002123 final int batteryLevelInt;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002124 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002125 batteryLevelInt = src.readInt();
Adam Lesinski3944c812015-11-13 15:54:59 -08002126 readBatteryLevelInt(batteryLevelInt, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002127 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002128 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
2129 + Integer.toHexString(batteryLevelInt)
2130 + " batteryLevel=" + cur.batteryLevel
2131 + " batteryTemp=" + cur.batteryTemperature
2132 + " batteryVolt=" + (int)cur.batteryVoltage);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002133 } else {
2134 batteryLevelInt = 0;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002135 }
2136
2137 if ((firstToken&DELTA_STATE_FLAG) != 0) {
2138 int stateInt = src.readInt();
2139 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002140 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
2141 & STATE_BATTERY_STATUS_MASK);
2142 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
2143 & STATE_BATTERY_HEALTH_MASK);
2144 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
2145 & STATE_BATTERY_PLUG_MASK);
2146 switch (cur.batteryPlugType) {
2147 case 1:
2148 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
2149 break;
2150 case 2:
2151 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
2152 break;
2153 case 3:
2154 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
2155 break;
2156 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002157 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002158 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
2159 + Integer.toHexString(stateInt)
2160 + " batteryStatus=" + cur.batteryStatus
2161 + " batteryHealth=" + cur.batteryHealth
2162 + " batteryPlugType=" + cur.batteryPlugType
2163 + " states=0x" + Integer.toHexString(cur.states));
2164 } else {
2165 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK));
2166 }
2167
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002168 if ((firstToken&DELTA_STATE2_FLAG) != 0) {
2169 cur.states2 = src.readInt();
2170 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
2171 + Integer.toHexString(cur.states2));
2172 }
2173
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002174 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002175 int indexes = src.readInt();
2176 int wakeLockIndex = indexes&0xffff;
2177 int wakeReasonIndex = (indexes>>16)&0xffff;
2178 if (wakeLockIndex != 0xffff) {
2179 cur.wakelockTag = cur.localWakelockTag;
2180 readHistoryTag(wakeLockIndex, cur.wakelockTag);
2181 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
2182 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
2183 } else {
2184 cur.wakelockTag = null;
2185 }
2186 if (wakeReasonIndex != 0xffff) {
2187 cur.wakeReasonTag = cur.localWakeReasonTag;
2188 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
2189 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
2190 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
2191 } else {
2192 cur.wakeReasonTag = null;
2193 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002194 cur.numReadInts += 1;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002195 } else {
2196 cur.wakelockTag = null;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002197 cur.wakeReasonTag = null;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002198 }
2199
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002200 if ((firstToken&DELTA_EVENT_FLAG) != 0) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002201 cur.eventTag = cur.localEventTag;
2202 final int codeAndIndex = src.readInt();
Dianne Hackborn099bc622014-01-22 13:39:16 -08002203 cur.eventCode = (codeAndIndex&0xffff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002204 final int index = ((codeAndIndex>>16)&0xffff);
2205 readHistoryTag(index, cur.eventTag);
2206 cur.numReadInts += 1;
2207 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
2208 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
2209 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002210 } else {
2211 cur.eventCode = HistoryItem.EVENT_NONE;
2212 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002213
2214 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) {
2215 cur.stepDetails = mReadHistoryStepDetails;
2216 cur.stepDetails.readFromParcel(src);
2217 } else {
2218 cur.stepDetails = null;
2219 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002220 }
2221
Dianne Hackbornfc064132014-06-02 12:42:12 -07002222 @Override
2223 public void commitCurrentHistoryBatchLocked() {
2224 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
2225 }
2226
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002227 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002228 if (!mHaveBatteryLevel || !mRecordingHistory) {
2229 return;
2230 }
2231
Dianne Hackborn40c87252014-03-19 16:55:40 -07002232 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002233 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates);
2234 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002235 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002236 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002237 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
2238 + Integer.toHexString(diffStates) + " lastDiff="
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002239 + Integer.toHexString(lastDiffStates) + " diff2="
2240 + Integer.toHexString(diffStates2) + " lastDiff2="
2241 + Integer.toHexString(lastDiffStates2));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002242 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002243 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002244 && (diffStates2&lastDiffStates2) == 0
2245 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
2246 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002247 && mHistoryLastWritten.stepDetails == null
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002248 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002249 || cur.eventCode == HistoryItem.EVENT_NONE)
2250 && mHistoryLastWritten.batteryLevel == cur.batteryLevel
2251 && mHistoryLastWritten.batteryStatus == cur.batteryStatus
2252 && mHistoryLastWritten.batteryHealth == cur.batteryHealth
2253 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
2254 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
2255 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002256 // We can merge this new change in with the last one. Merging is
Dianne Hackborn40c87252014-03-19 16:55:40 -07002257 // allowed as long as only the states have changed, and within those states
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002258 // as long as no bit has changed both between now and the last entry, as
2259 // well as the last entry and the one before it (so we capture any toggles).
2260 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002261 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
2262 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
2263 mHistoryBufferLastPos = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002264 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002265 // If the last written history had a wakelock tag, we need to retain it.
2266 // Note that the condition above made sure that we aren't in a case where
2267 // both it and the current history item have a wakelock tag.
2268 if (mHistoryLastWritten.wakelockTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002269 cur.wakelockTag = cur.localWakelockTag;
2270 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002271 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002272 // If the last written history had a wake reason tag, we need to retain it.
2273 // Note that the condition above made sure that we aren't in a case where
2274 // both it and the current history item have a wakelock tag.
2275 if (mHistoryLastWritten.wakeReasonTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002276 cur.wakeReasonTag = cur.localWakeReasonTag;
2277 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002278 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002279 // If the last written history had an event, we need to retain it.
2280 // Note that the condition above made sure that we aren't in a case where
2281 // both it and the current history item have an event.
2282 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002283 cur.eventCode = mHistoryLastWritten.eventCode;
2284 cur.eventTag = cur.localEventTag;
2285 cur.eventTag.setTo(mHistoryLastWritten.eventTag);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002286 }
Dianne Hackborn1fadab52011-04-14 17:57:33 -07002287 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002288 }
2289
2290 final int dataSize = mHistoryBuffer.dataSize();
2291 if (dataSize >= MAX_HISTORY_BUFFER) {
2292 if (!mHistoryOverflow) {
2293 mHistoryOverflow = true;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002294 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
2295 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002296 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002297 }
2298
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002299 // After overflow, we allow various bit-wise states to settle to 0.
2300 boolean writeAnyway = false;
2301 final int curStates = cur.states & HistoryItem.SETTLE_TO_ZERO_STATES
2302 & mActiveHistoryStates;
2303 if (mHistoryLastWritten.states != curStates) {
2304 // mActiveHistoryStates keeps track of which bits in .states are now being
2305 // forced to 0.
2306 int old = mActiveHistoryStates;
2307 mActiveHistoryStates &= curStates | ~HistoryItem.SETTLE_TO_ZERO_STATES;
2308 writeAnyway |= old != mActiveHistoryStates;
2309 }
2310 final int curStates2 = cur.states2 & HistoryItem.SETTLE_TO_ZERO_STATES2
2311 & mActiveHistoryStates2;
2312 if (mHistoryLastWritten.states2 != curStates2) {
2313 // mActiveHistoryStates2 keeps track of which bits in .states2 are now being
2314 // forced to 0.
2315 int old = mActiveHistoryStates2;
2316 mActiveHistoryStates2 &= curStates2 | ~HistoryItem.SETTLE_TO_ZERO_STATES2;
2317 writeAnyway |= old != mActiveHistoryStates2;
2318 }
2319
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002320 // Once we've reached the maximum number of items, we only
2321 // record changes to the battery level and the most interesting states.
2322 // Once we've reached the maximum maximum number of items, we only
2323 // record changes to the battery level.
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002324 if (!writeAnyway && mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002325 (dataSize >= MAX_MAX_HISTORY_BUFFER
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002326 || ((mHistoryLastWritten.states^cur.states)
Dianne Hackborn3251b902014-06-20 14:40:53 -07002327 & HistoryItem.MOST_INTERESTING_STATES) == 0
2328 || ((mHistoryLastWritten.states2^cur.states2)
2329 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002330 return;
2331 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002332
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002333 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002334 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002335 }
2336
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002337 if (dataSize == 0) {
2338 // The history is currently empty; we need it to start with a time stamp.
2339 cur.currentTime = System.currentTimeMillis();
2340 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur);
2341 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002342 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002343 }
2344
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002345 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
2346 HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002347 if (mIteratingHistory) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002348 throw new IllegalStateException("Can't do this while iterating history!");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002349 }
2350 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
2351 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002352 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002353 mHistoryLastWritten.states &= mActiveHistoryStates;
2354 mHistoryLastWritten.states2 &= mActiveHistoryStates2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002355 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07002356 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002357 cur.wakelockTag = null;
2358 cur.wakeReasonTag = null;
2359 cur.eventCode = HistoryItem.EVENT_NONE;
2360 cur.eventTag = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002361 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
2362 + " now " + mHistoryBuffer.dataPosition()
2363 + " size is now " + mHistoryBuffer.dataSize());
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002364 }
2365
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002366 int mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002367 int mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002368
Dianne Hackborn40c87252014-03-19 16:55:40 -07002369 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002370 if (mTrackRunningHistoryElapsedRealtime != 0) {
2371 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
2372 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
2373 if (diffUptime < (diffElapsed-20)) {
2374 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
2375 mHistoryAddTmp.setTo(mHistoryLastWritten);
2376 mHistoryAddTmp.wakelockTag = null;
2377 mHistoryAddTmp.wakeReasonTag = null;
2378 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
2379 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
2380 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
2381 }
2382 }
2383 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
2384 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
2385 mTrackRunningHistoryUptime = uptimeMs;
2386 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
2387 }
2388
2389 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
2390 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002391
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002392 if (!USE_OLD_HISTORY) {
2393 return;
2394 }
2395
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002396 if (!mHaveBatteryLevel || !mRecordingHistory) {
2397 return;
2398 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002399
2400 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002401 // and no states have since the last recorded entry changed and
2402 // are now resetting back to their original value, then just collapse
2403 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002404 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002405 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002406 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0
2407 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002408 // If the current is the same as the one before, then we no
2409 // longer need the entry.
2410 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002411 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002412 && mHistoryLastEnd.sameNonEvent(cur)) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002413 mHistoryLastEnd.next = null;
2414 mHistoryEnd.next = mHistoryCache;
2415 mHistoryCache = mHistoryEnd;
2416 mHistoryEnd = mHistoryLastEnd;
2417 mHistoryLastEnd = null;
2418 } else {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002419 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates);
2420 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002421 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002422 }
2423 return;
2424 }
2425
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002426 mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002427 mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002428
2429 if (mNumHistoryItems == MAX_HISTORY_ITEMS
2430 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002431 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002432 }
2433
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002434 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
2435 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002436 // record changes to the battery level and the most interesting states.
2437 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002438 // record changes to the battery level.
2439 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002440 == cur.batteryLevel &&
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002441 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002442 || ((mHistoryEnd.states^(cur.states&mActiveHistoryStates))
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002443 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002444 return;
2445 }
2446 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002447
Dianne Hackborn40c87252014-03-19 16:55:40 -07002448 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002449 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002450
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002451 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002452 String name, int uid) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002453 mHistoryCur.eventCode = code;
2454 mHistoryCur.eventTag = mHistoryCur.localEventTag;
2455 mHistoryCur.eventTag.string = name;
2456 mHistoryCur.eventTag.uid = uid;
Dianne Hackborn4590e522014-03-24 13:36:46 -07002457 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002458 }
2459
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002460 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002461 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002462 if (rec != null) {
2463 mHistoryCache = rec.next;
2464 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002465 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002466 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002467 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002468
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002469 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002470 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002471
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002472 void addHistoryRecordLocked(HistoryItem rec) {
2473 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002474 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002475 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002476 if (mHistoryEnd != null) {
2477 mHistoryEnd.next = rec;
2478 mHistoryEnd = rec;
2479 } else {
2480 mHistory = mHistoryEnd = rec;
2481 }
2482 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002483
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002484 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002485 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002486 if (USE_OLD_HISTORY) {
2487 if (mHistory != null) {
2488 mHistoryEnd.next = mHistoryCache;
2489 mHistoryCache = mHistory;
2490 mHistory = mHistoryLastEnd = mHistoryEnd = null;
2491 }
2492 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002493 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002494
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002495 mHistoryBaseTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002496 mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002497 mTrackRunningHistoryElapsedRealtime = 0;
2498 mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002499
2500 mHistoryBuffer.setDataSize(0);
2501 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002502 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002503 mHistoryLastLastWritten.clear();
2504 mHistoryLastWritten.clear();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002505 mHistoryTagPool.clear();
2506 mNextHistoryTagIdx = 0;
2507 mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002508 mHistoryBufferLastPos = -1;
2509 mHistoryOverflow = false;
Dianne Hackborn0c820db2015-04-14 17:47:34 -07002510 mActiveHistoryStates = 0xffffffff;
2511 mActiveHistoryStates2 = 0xffffffff;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002512 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002513
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002514 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
2515 long realtime) {
Adam Lesinskie283d332015-04-16 12:29:25 -07002516 mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002517
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002518 boolean unpluggedScreenOff = unplugged && screenOff;
2519 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
2520 updateKernelWakelocksLocked();
Adam Lesinski72478f02015-06-17 15:39:43 -07002521 if (DEBUG_ENERGY_CPU) {
2522 Slog.d(TAG, "Updating cpu time because screen is now " +
2523 (unpluggedScreenOff ? "off" : "on"));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002524 }
Adam Lesinski72478f02015-06-17 15:39:43 -07002525 updateCpuTimeLocked();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002526 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527 }
2528 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002529
Dianne Hackborn099bc622014-01-22 13:39:16 -08002530 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
2531 mIsolatedUids.put(isolatedUid, appUid);
2532 }
2533
Adam Lesinski61db88f2015-07-01 15:05:07 -07002534 /**
2535 * Schedules a read of the latest cpu times before removing the isolated UID.
2536 * @see #removeIsolatedUidLocked(int)
2537 */
2538 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002539 int curUid = mIsolatedUids.get(isolatedUid, -1);
2540 if (curUid == appUid) {
Adam Lesinski61db88f2015-07-01 15:05:07 -07002541 if (mExternalSync != null) {
2542 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid);
2543 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08002544 }
2545 }
2546
Adam Lesinski61db88f2015-07-01 15:05:07 -07002547 /**
2548 * This should only be called after the cpu times have been read.
2549 * @see #scheduleRemoveIsolatedUidLocked(int, int)
2550 */
2551 public void removeIsolatedUidLocked(int isolatedUid) {
2552 mIsolatedUids.delete(isolatedUid);
2553 mKernelUidCpuTimeReader.removeUid(isolatedUid);
2554 }
2555
Dianne Hackborn099bc622014-01-22 13:39:16 -08002556 public int mapUid(int uid) {
2557 int isolated = mIsolatedUids.get(uid, -1);
2558 return isolated > 0 ? isolated : uid;
2559 }
2560
2561 public void noteEventLocked(int code, String name, int uid) {
2562 uid = mapUid(uid);
Dianne Hackborn37de0982014-05-09 09:32:18 -07002563 if (!mActiveEvents.updateState(code, name, uid, 0)) {
2564 return;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002565 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07002566 final long elapsedRealtime = SystemClock.elapsedRealtime();
2567 final long uptime = SystemClock.uptimeMillis();
2568 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002569 }
2570
Dianne Hackbornd48954f2015-07-22 17:20:33 -07002571 boolean ensureStartClockTime(final long currentTime) {
2572 final long ABOUT_ONE_YEAR = 365*24*60*60*1000L;
2573 if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) {
2574 // If the start clock time has changed by more than a year, then presumably
2575 // the previous time was completely bogus. So we are going to figure out a
2576 // new time based on how much time has elapsed since we started counting.
2577 mStartClockTime = currentTime - (SystemClock.elapsedRealtime()-(mRealtimeStart/1000));
2578 return true;
2579 }
2580 return false;
2581 }
2582
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07002583 public void noteCurrentTimeChangedLocked() {
2584 final long currentTime = System.currentTimeMillis();
2585 final long elapsedRealtime = SystemClock.elapsedRealtime();
2586 final long uptime = SystemClock.uptimeMillis();
2587 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
Dianne Hackbornd48954f2015-07-22 17:20:33 -07002588 ensureStartClockTime(currentTime);
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07002589 }
2590
Dianne Hackborn61659e52014-07-09 16:13:01 -07002591 public void noteProcessStartLocked(String name, int uid) {
2592 uid = mapUid(uid);
2593 if (isOnBattery()) {
2594 Uid u = getUidStatsLocked(uid);
2595 u.getProcessStatsLocked(name).incStartsLocked();
2596 }
2597 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) {
2598 return;
2599 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002600 if (!mRecordAllHistory) {
2601 return;
2602 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07002603 final long elapsedRealtime = SystemClock.elapsedRealtime();
2604 final long uptime = SystemClock.uptimeMillis();
2605 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid);
2606 }
2607
Dianne Hackborn1e01d162014-12-04 17:46:42 -08002608 public void noteProcessCrashLocked(String name, int uid) {
2609 uid = mapUid(uid);
2610 if (isOnBattery()) {
2611 Uid u = getUidStatsLocked(uid);
2612 u.getProcessStatsLocked(name).incNumCrashesLocked();
2613 }
2614 }
2615
2616 public void noteProcessAnrLocked(String name, int uid) {
2617 uid = mapUid(uid);
2618 if (isOnBattery()) {
2619 Uid u = getUidStatsLocked(uid);
2620 u.getProcessStatsLocked(name).incNumAnrsLocked();
2621 }
2622 }
2623
Dianne Hackborna8d10942015-11-19 17:55:19 -08002624 public void noteUidProcessStateLocked(int uid, int state) {
Dianne Hackborn61659e52014-07-09 16:13:01 -07002625 uid = mapUid(uid);
Dianne Hackborna8d10942015-11-19 17:55:19 -08002626 getUidStatsLocked(uid).updateUidProcessStateLocked(state);
Dianne Hackborn61659e52014-07-09 16:13:01 -07002627 }
2628
2629 public void noteProcessFinishLocked(String name, int uid) {
2630 uid = mapUid(uid);
2631 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) {
2632 return;
2633 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002634 if (!mRecordAllHistory) {
2635 return;
2636 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08002637 final long elapsedRealtime = SystemClock.elapsedRealtime();
2638 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002639 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid);
Dianne Hackborn61659e52014-07-09 16:13:01 -07002640 }
2641
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002642 public void noteSyncStartLocked(String name, int uid) {
2643 uid = mapUid(uid);
2644 final long elapsedRealtime = SystemClock.elapsedRealtime();
2645 final long uptime = SystemClock.uptimeMillis();
2646 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime);
2647 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
2648 return;
2649 }
2650 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid);
2651 }
2652
2653 public void noteSyncFinishLocked(String name, int uid) {
2654 uid = mapUid(uid);
2655 final long elapsedRealtime = SystemClock.elapsedRealtime();
2656 final long uptime = SystemClock.uptimeMillis();
2657 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime);
2658 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
2659 return;
2660 }
2661 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid);
2662 }
2663
2664 public void noteJobStartLocked(String name, int uid) {
2665 uid = mapUid(uid);
2666 final long elapsedRealtime = SystemClock.elapsedRealtime();
2667 final long uptime = SystemClock.uptimeMillis();
2668 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime);
2669 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
2670 return;
2671 }
2672 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid);
2673 }
2674
2675 public void noteJobFinishLocked(String name, int uid) {
2676 uid = mapUid(uid);
2677 final long elapsedRealtime = SystemClock.elapsedRealtime();
2678 final long uptime = SystemClock.uptimeMillis();
2679 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime);
2680 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
2681 return;
2682 }
2683 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid);
2684 }
2685
Dianne Hackborn1e383822015-04-10 14:02:33 -07002686 public void noteAlarmStartLocked(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_START, name, uid, 0)) {
2694 return;
2695 }
2696 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid);
2697 }
2698
2699 public void noteAlarmFinishLocked(String name, int uid) {
2700 if (!mRecordAllHistory) {
2701 return;
2702 }
2703 uid = mapUid(uid);
2704 final long elapsedRealtime = SystemClock.elapsedRealtime();
2705 final long uptime = SystemClock.uptimeMillis();
2706 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) {
2707 return;
2708 }
2709 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid);
2710 }
2711
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002712 private void requestWakelockCpuUpdate() {
2713 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
2714 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
2715 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
2716 }
2717 }
2718
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002719 private void requestImmediateCpuUpdate() {
2720 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2721 mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS);
2722 }
2723
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002724 public void setRecordAllHistoryLocked(boolean enabled) {
2725 mRecordAllHistory = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002726 if (!enabled) {
2727 // Clear out any existing state.
2728 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK);
Dianne Hackborn1e383822015-04-10 14:02:33 -07002729 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002730 // Record the currently running processes as stopping, now that we are no
2731 // longer tracking them.
2732 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
2733 HistoryItem.EVENT_PROC);
2734 if (active != null) {
2735 long mSecRealtime = SystemClock.elapsedRealtime();
2736 final long mSecUptime = SystemClock.uptimeMillis();
2737 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
2738 SparseIntArray uids = ent.getValue();
2739 for (int j=0; j<uids.size(); j++) {
2740 addHistoryEventLocked(mSecRealtime, mSecUptime,
2741 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j));
2742 }
2743 }
2744 }
2745 } else {
2746 // Record the currently running processes as starting, now that we are tracking them.
2747 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
2748 HistoryItem.EVENT_PROC);
2749 if (active != null) {
2750 long mSecRealtime = SystemClock.elapsedRealtime();
2751 final long mSecUptime = SystemClock.uptimeMillis();
2752 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
2753 SparseIntArray uids = ent.getValue();
2754 for (int j=0; j<uids.size(); j++) {
2755 addHistoryEventLocked(mSecRealtime, mSecUptime,
2756 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j));
2757 }
2758 }
2759 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002760 }
2761 }
2762
Dianne Hackborn9a755432014-05-15 17:05:22 -07002763 public void setNoAutoReset(boolean enabled) {
2764 mNoAutoReset = enabled;
2765 }
2766
2767 private String mInitialAcquireWakeName;
2768 private int mInitialAcquireWakeUid = -1;
2769
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002770 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002771 boolean unimportantForLogging, long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002772 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002773 if (type == WAKE_TYPE_PARTIAL) {
2774 // Only care about partial wake locks, since full wake locks
2775 // will be canceled when the user puts the screen to sleep.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002776 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002777 if (historyName == null) {
2778 historyName = name;
2779 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002780 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002781 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
2782 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002783 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002784 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002785 }
2786 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002787 if (mWakeLockNesting == 0) {
2788 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
2789 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
2790 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002791 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002792 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002793 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002794 mWakeLockImportant = !unimportantForLogging;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002795 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002796 } else if (!mWakeLockImportant && !unimportantForLogging
2797 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002798 if (mHistoryLastWritten.wakelockTag != null) {
2799 // We'll try to update the last tag.
2800 mHistoryLastWritten.wakelockTag = null;
2801 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002802 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002803 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002804 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002805 }
2806 mWakeLockImportant = true;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002807 }
2808 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002809 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002810 if (uid >= 0) {
Adam Lesinski72478f02015-06-17 15:39:43 -07002811 if (mOnBatteryScreenOffTimeBase.isRunning()) {
2812 // We only update the cpu time when a wake lock is acquired if the screen is off.
2813 // If the screen is on, we don't distribute the power amongst partial wakelocks.
2814 if (DEBUG_ENERGY_CPU) {
2815 Slog.d(TAG, "Updating cpu time because of +wake_lock");
2816 }
2817 requestWakelockCpuUpdate();
2818 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002819 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002820 }
2821 }
2822
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002823 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type,
2824 long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002825 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002826 if (type == WAKE_TYPE_PARTIAL) {
2827 mWakeLockNesting--;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002828 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002829 if (historyName == null) {
2830 historyName = name;
2831 }
2832 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
2833 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002834 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002835 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002836 }
2837 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002838 if (mWakeLockNesting == 0) {
2839 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
2840 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
2841 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn37de0982014-05-09 09:32:18 -07002842 mInitialAcquireWakeName = null;
2843 mInitialAcquireWakeUid = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002844 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002845 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002846 }
2847 if (uid >= 0) {
Adam Lesinski72478f02015-06-17 15:39:43 -07002848 if (mOnBatteryScreenOffTimeBase.isRunning()) {
2849 if (DEBUG_ENERGY_CPU) {
2850 Slog.d(TAG, "Updating cpu time because of -wake_lock");
2851 }
2852 requestWakelockCpuUpdate();
2853 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002854 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002855 }
2856 }
2857
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002858 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
2859 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002860 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002861 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002862 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002863 for (int i=0; i<N; i++) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002864 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002865 elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002866 }
2867 }
2868
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002869 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
2870 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002871 String newHistoryName, int newType, boolean newUnimportantForLogging) {
2872 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002873 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002874 // For correct semantics, we start the need worksources first, so that we won't
2875 // make inappropriate history items as if all wake locks went away and new ones
2876 // appeared. This is okay because tracking of wake locks allows nesting.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002877 final int NN = newWs.size();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002878 for (int i=0; i<NN; i++) {
2879 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002880 newUnimportantForLogging, elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002881 }
2882 final int NO = ws.size();
2883 for (int i=0; i<NO; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002884 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002885 }
2886 }
2887
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002888 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
2889 String historyName, int type) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002890 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002891 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002892 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002893 for (int i=0; i<N; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002894 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002895 }
2896 }
2897
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002898 void aggregateLastWakeupUptimeLocked(long uptimeMs) {
2899 if (mLastWakeupReason != null) {
2900 long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002901 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
2902 timer.addCurrentReportedCount(1);
2903 timer.addCurrentReportedTotalTime(deltaUptime * 1000); // time is in microseconds
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002904 mLastWakeupReason = null;
2905 }
2906 }
2907
2908 public void noteWakeupReasonLocked(String reason) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002909 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002910 final long uptime = SystemClock.uptimeMillis();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002911 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": "
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002912 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002913 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002914 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
2915 mHistoryCur.wakeReasonTag.string = reason;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002916 mHistoryCur.wakeReasonTag.uid = 0;
2917 mLastWakeupReason = reason;
2918 mLastWakeupUptimeMs = uptime;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002919 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002920 }
2921
Adam Lesinski72478f02015-06-17 15:39:43 -07002922 public boolean startAddingCpuLocked() {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002923 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
Adam Lesinski72478f02015-06-17 15:39:43 -07002924 return mOnBatteryInternal;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002925 }
2926
Adam Lesinski72478f02015-06-17 15:39:43 -07002927 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime,
2928 int statSystemTime, int statIOWaitTime, int statIrqTime,
2929 int statSoftIrqTime, int statIdleTime) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002930 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
2931 + " user=" + statUserTime + " sys=" + statSystemTime
2932 + " io=" + statIOWaitTime + " irq=" + statIrqTime
2933 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime);
2934 mCurStepCpuUserTime += totalUTime;
2935 mCurStepCpuSystemTime += totalSTime;
2936 mCurStepStatUserTime += statUserTime;
2937 mCurStepStatSystemTime += statSystemTime;
2938 mCurStepStatIOWaitTime += statIOWaitTime;
2939 mCurStepStatIrqTime += statIrqTime;
2940 mCurStepStatSoftIrqTime += statSoftIrqTime;
2941 mCurStepStatIdleTime += statIdleTime;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002942 }
2943
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002944 public void noteProcessDiedLocked(int uid, int pid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002945 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002946 Uid u = mUidStats.get(uid);
2947 if (u != null) {
2948 u.mPids.remove(pid);
2949 }
2950 }
2951
2952 public long getProcessWakeTime(int uid, int pid, long realtime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002953 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002954 Uid u = mUidStats.get(uid);
2955 if (u != null) {
2956 Uid.Pid p = u.mPids.get(pid);
2957 if (p != null) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002958 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002959 }
2960 }
2961 return 0;
2962 }
2963
2964 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002965 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002966 Uid u = mUidStats.get(uid);
2967 if (u != null) {
2968 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
2969 }
2970 }
2971
Dianne Hackborn287952c2010-09-22 22:34:31 -07002972 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002973 uid = mapUid(uid);
Dianne Hackborn287952c2010-09-22 22:34:31 -07002974 Uid u = mUidStats.get(uid);
2975 if (u != null) {
2976 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
2977 }
2978 }
2979
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002980 int mSensorNesting;
2981
2982 public void noteStartSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002983 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002984 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002985 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002986 if (mSensorNesting == 0) {
2987 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
2988 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
2989 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002990 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002991 }
2992 mSensorNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002993 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002994 }
2995
2996 public void noteStopSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002997 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002998 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002999 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003000 mSensorNesting--;
3001 if (mSensorNesting == 0) {
3002 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
3003 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
3004 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003005 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003006 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003007 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003008 }
3009
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003010 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003011
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003012 public void noteStartGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003013 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003014 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003015 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003016 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003017 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003018 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
3019 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003020 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003021 }
3022 mGpsNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003023 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003024 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003025
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003026 public void noteStopGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003027 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003028 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003029 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003030 mGpsNesting--;
3031 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003032 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003033 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
3034 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003035 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003036 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003037 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003039
Jeff Browne95c3cd2014-05-02 16:59:26 -07003040 public void noteScreenStateLocked(int state) {
3041 if (mScreenState != state) {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08003042 recordDailyStatsIfNeededLocked(true);
Jeff Browne95c3cd2014-05-02 16:59:26 -07003043 final int oldState = mScreenState;
3044 mScreenState = state;
3045 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
3046 + ", newState=" + Display.stateToString(state));
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003047
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003048 if (state != Display.STATE_UNKNOWN) {
3049 int stepState = state-1;
3050 if (stepState < 4) {
3051 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState;
3052 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_SCREEN_STATE) | stepState;
3053 } else {
3054 Slog.wtf(TAG, "Unexpected screen state: " + state);
3055 }
3056 }
3057
Jeff Browne95c3cd2014-05-02 16:59:26 -07003058 if (state == Display.STATE_ON) {
3059 // Screen turning on.
3060 final long elapsedRealtime = SystemClock.elapsedRealtime();
3061 final long uptime = SystemClock.uptimeMillis();
3062 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
3063 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
3064 + Integer.toHexString(mHistoryCur.states));
3065 addHistoryRecordLocked(elapsedRealtime, uptime);
3066 mScreenOnTimer.startRunningLocked(elapsedRealtime);
3067 if (mScreenBrightnessBin >= 0) {
3068 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
3069 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003070
Jeff Browne95c3cd2014-05-02 16:59:26 -07003071 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false,
3072 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003073
Jeff Browne95c3cd2014-05-02 16:59:26 -07003074 // Fake a wake lock, so we consider the device waked as long
3075 // as the screen is on.
3076 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
3077 elapsedRealtime, uptime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003078
Jeff Browne95c3cd2014-05-02 16:59:26 -07003079 // Update discharge amounts.
3080 if (mOnBatteryInternal) {
3081 updateDischargeScreenLevelsLocked(false, true);
3082 }
3083 } else if (oldState == Display.STATE_ON) {
3084 // Screen turning off or dozing.
3085 final long elapsedRealtime = SystemClock.elapsedRealtime();
3086 final long uptime = SystemClock.uptimeMillis();
3087 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
3088 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
3089 + Integer.toHexString(mHistoryCur.states));
3090 addHistoryRecordLocked(elapsedRealtime, uptime);
3091 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
3092 if (mScreenBrightnessBin >= 0) {
3093 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
3094 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003095
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003096 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL,
Jeff Browne95c3cd2014-05-02 16:59:26 -07003097 elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003098
Jeff Browne95c3cd2014-05-02 16:59:26 -07003099 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
3100 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003101
Jeff Browne95c3cd2014-05-02 16:59:26 -07003102 // Update discharge amounts.
3103 if (mOnBatteryInternal) {
3104 updateDischargeScreenLevelsLocked(true, false);
3105 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08003106 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07003107 }
3108 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003109
Dianne Hackborn617f8772009-03-31 15:04:46 -07003110 public void noteScreenBrightnessLocked(int brightness) {
3111 // Bin the brightness.
3112 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
3113 if (bin < 0) bin = 0;
3114 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
3115 if (mScreenBrightnessBin != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003116 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003117 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003118 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
3119 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003120 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
3121 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003122 addHistoryRecordLocked(elapsedRealtime, uptime);
Jeff Browne95c3cd2014-05-02 16:59:26 -07003123 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003124 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003125 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003126 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003127 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003128 }
3129 mScreenBrightnessBin = bin;
3130 }
3131 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003132
Dianne Hackborn617f8772009-03-31 15:04:46 -07003133 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003134 if (mOnBatteryInternal) {
3135 uid = mapUid(uid);
3136 getUidStatsLocked(uid).noteUserActivityLocked(event);
3137 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003138 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003139
Dianne Hackborn280a64e2015-07-13 14:48:08 -07003140 public void noteWakeUpLocked(String reason, int reasonUid) {
3141 final long elapsedRealtime = SystemClock.elapsedRealtime();
3142 final long uptime = SystemClock.uptimeMillis();
3143 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP,
3144 reason, reasonUid);
3145 }
3146
Jeff Browne95c3cd2014-05-02 16:59:26 -07003147 public void noteInteractiveLocked(boolean interactive) {
3148 if (mInteractive != interactive) {
3149 final long elapsedRealtime = SystemClock.elapsedRealtime();
3150 mInteractive = interactive;
3151 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
3152 if (interactive) {
3153 mInteractiveTimer.startRunningLocked(elapsedRealtime);
3154 } else {
3155 mInteractiveTimer.stopRunningLocked(elapsedRealtime);
3156 }
3157 }
3158 }
3159
Dianne Hackborn1e01d162014-12-04 17:46:42 -08003160 public void noteConnectivityChangedLocked(int type, String extra) {
3161 final long elapsedRealtime = SystemClock.elapsedRealtime();
3162 final long uptime = SystemClock.uptimeMillis();
3163 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
3164 extra, type);
3165 mNumConnectivityChange++;
3166 }
3167
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003168 public void noteMobileRadioPowerState(int powerState, long timestampNs) {
3169 final long elapsedRealtime = SystemClock.elapsedRealtime();
3170 final long uptime = SystemClock.uptimeMillis();
3171 if (mMobileRadioPowerState != powerState) {
3172 long realElapsedRealtimeMs;
3173 final boolean active =
3174 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
3175 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
3176 if (active) {
Dianne Hackbornf7097a52014-05-13 09:56:14 -07003177 mMobileRadioActiveStartTime = realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003178 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
3179 } else {
3180 realElapsedRealtimeMs = timestampNs / (1000*1000);
Dianne Hackbornf7097a52014-05-13 09:56:14 -07003181 long lastUpdateTimeMs = mMobileRadioActiveStartTime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003182 if (realElapsedRealtimeMs < lastUpdateTimeMs) {
3183 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
3184 + " is before start time " + lastUpdateTimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003185 realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003186 } else if (realElapsedRealtimeMs < elapsedRealtime) {
3187 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
3188 - realElapsedRealtimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003189 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003190 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
3191 }
3192 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
3193 + Integer.toHexString(mHistoryCur.states));
3194 addHistoryRecordLocked(elapsedRealtime, uptime);
3195 mMobileRadioPowerState = powerState;
3196 if (active) {
3197 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
3198 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
3199 } else {
3200 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003201 updateMobileRadioStateLocked(realElapsedRealtimeMs);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003202 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003203 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003204 }
3205 }
3206
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003207 public void notePowerSaveMode(boolean enabled) {
3208 if (mPowerSaveModeEnabled != enabled) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003209 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0;
3210 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState;
3211 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003212 final long elapsedRealtime = SystemClock.elapsedRealtime();
3213 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003214 mPowerSaveModeEnabled = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003215 if (enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003216 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
3217 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003218 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003219 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003220 } else {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003221 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
3222 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003223 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003224 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003225 }
3226 addHistoryRecordLocked(elapsedRealtime, uptime);
3227 }
3228 }
3229
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003230 public void noteDeviceIdleModeLocked(int mode, String activeReason, int activeUid) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003231 final long elapsedRealtime = SystemClock.elapsedRealtime();
3232 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003233 boolean nowIdling = mode == DEVICE_IDLE_MODE_FULL;
3234 if (mDeviceIdling && !nowIdling && activeReason == null) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003235 // We don't go out of general idling mode until explicitly taken out of
3236 // device idle through going active or significant motion.
3237 nowIdling = true;
3238 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003239 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT;
3240 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) {
3241 // We don't go out of general light idling mode until explicitly taken out of
3242 // device idle through going active or significant motion.
3243 nowLightIdling = true;
3244 }
3245 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) {
3246 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
3247 activeReason, activeUid);
3248 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003249 if (mDeviceIdling != nowIdling) {
3250 mDeviceIdling = nowIdling;
3251 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0;
3252 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState;
3253 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003254 if (nowIdling) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003255 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime);
3256 } else {
3257 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime);
3258 }
3259 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003260 if (mDeviceLightIdling != nowLightIdling) {
3261 mDeviceLightIdling = nowLightIdling;
3262 if (nowLightIdling) {
3263 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003264 } else {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003265 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003266 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003267 }
3268 if (mDeviceIdleMode != mode) {
3269 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK)
3270 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT);
3271 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: "
3272 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003273 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003274 long lastDuration = elapsedRealtime - mLastIdleTimeStart;
3275 mLastIdleTimeStart = elapsedRealtime;
3276 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) {
3277 if (lastDuration > mLongestLightIdleTime) {
3278 mLongestLightIdleTime = lastDuration;
3279 }
3280 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime);
3281 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_FULL) {
3282 if (lastDuration > mLongestFullIdleTime) {
3283 mLongestFullIdleTime = lastDuration;
3284 }
3285 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime);
3286 }
3287 if (mode == DEVICE_IDLE_MODE_LIGHT) {
3288 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime);
3289 } else if (mode == DEVICE_IDLE_MODE_FULL) {
3290 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime);
3291 }
3292 mDeviceIdleMode = mode;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003293 }
3294 }
3295
3296 public void notePackageInstalledLocked(String pkgName, int versionCode) {
3297 final long elapsedRealtime = SystemClock.elapsedRealtime();
3298 final long uptime = SystemClock.uptimeMillis();
3299 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED,
3300 pkgName, versionCode);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003301 PackageChange pc = new PackageChange();
3302 pc.mPackageName = pkgName;
3303 pc.mUpdate = true;
3304 pc.mVersionCode = versionCode;
3305 addPackageChange(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003306 }
3307
3308 public void notePackageUninstalledLocked(String pkgName) {
3309 final long elapsedRealtime = SystemClock.elapsedRealtime();
3310 final long uptime = SystemClock.uptimeMillis();
3311 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
3312 pkgName, 0);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003313 PackageChange pc = new PackageChange();
3314 pc.mPackageName = pkgName;
3315 pc.mUpdate = true;
3316 addPackageChange(pc);
3317 }
3318
3319 private void addPackageChange(PackageChange pc) {
3320 if (mDailyPackageChanges == null) {
3321 mDailyPackageChanges = new ArrayList<>();
3322 }
3323 mDailyPackageChanges.add(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003324 }
3325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326 public void notePhoneOnLocked() {
3327 if (!mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003328 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003329 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003330 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003331 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
3332 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003333 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003334 mPhoneOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003335 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003336 }
3337 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 public void notePhoneOffLocked() {
3340 if (mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003341 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003342 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003343 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003344 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
3345 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003346 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003347 mPhoneOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003348 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 }
3350 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003351
Dianne Hackborn3251b902014-06-20 14:40:53 -07003352 void stopAllPhoneSignalStrengthTimersLocked(int except) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003353 final long elapsedRealtime = SystemClock.elapsedRealtime();
Wink Saville52840902011-02-18 12:40:47 -08003354 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003355 if (i == except) {
3356 continue;
3357 }
3358 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003359 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003360 }
3361 }
3362 }
3363
Dianne Hackborne4a59512010-12-07 11:08:07 -08003364 private int fixPhoneServiceState(int state, int signalBin) {
3365 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
3366 // In this case we will always be STATE_OUT_OF_SERVICE, so need
3367 // to infer that we are scanning from other data.
3368 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08003369 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003370 state = ServiceState.STATE_IN_SERVICE;
3371 }
3372 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003373
Dianne Hackborne4a59512010-12-07 11:08:07 -08003374 return state;
3375 }
3376
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003377 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003378 boolean scanning = false;
3379 boolean newHistory = false;
3380
3381 mPhoneServiceStateRaw = state;
3382 mPhoneSimStateRaw = simState;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003383 mPhoneSignalStrengthBinRaw = strengthBin;
3384
3385 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003386 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne4a59512010-12-07 11:08:07 -08003387
3388 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
3389 // In this case we will always be STATE_OUT_OF_SERVICE, so need
3390 // to infer that we are scanning from other data.
3391 if (state == ServiceState.STATE_OUT_OF_SERVICE
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003392 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003393 state = ServiceState.STATE_IN_SERVICE;
3394 }
3395 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003396
3397 // If the phone is powered off, stop all timers.
3398 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003399 strengthBin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07003400
Dianne Hackborne4a59512010-12-07 11:08:07 -08003401 // If we are in service, make sure the correct signal string timer is running.
3402 } else if (state == ServiceState.STATE_IN_SERVICE) {
3403 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003404
3405 // If we're out of service, we are in the lowest signal strength
3406 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07003407 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003408 scanning = true;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003409 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07003410 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003411 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08003412 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003413 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
3414 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003415 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
Amith Yamasanif37447b2009-10-08 18:28:01 -07003416 }
3417 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003418
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003419 if (!scanning) {
3420 // If we are no longer scanning, then stop the scanning timer.
3421 if (mPhoneSignalScanningTimer.isRunningLocked()) {
3422 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
3423 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
3424 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08003425 newHistory = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003426 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003427 }
3428 }
3429
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003430 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003431 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
3432 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003433 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003434 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08003435 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003436 mPhoneServiceState = state;
3437 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08003438
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003439 if (mPhoneSignalStrengthBin != strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003440 if (mPhoneSignalStrengthBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003441 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003442 elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003443 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003444 if (strengthBin >= 0) {
3445 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003446 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003447 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07003448 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
3449 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003450 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
Dianne Hackborne4a59512010-12-07 11:08:07 -08003451 + Integer.toHexString(mHistoryCur.states));
3452 newHistory = true;
3453 } else {
Dianne Hackborn3251b902014-06-20 14:40:53 -07003454 stopAllPhoneSignalStrengthTimersLocked(-1);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003455 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003456 mPhoneSignalStrengthBin = strengthBin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08003457 }
3458
3459 if (newHistory) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07003460 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003461 }
3462 }
3463
3464 /**
3465 * Telephony stack updates the phone state.
3466 * @param state phone state from ServiceState.getState()
3467 */
3468 public void notePhoneStateLocked(int state, int simState) {
3469 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003470 }
3471
Wink Savillee9b06d72009-05-18 21:47:50 -07003472 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07003473 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08003474 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08003475 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003476 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003477
Dianne Hackborn627bba72009-03-24 22:32:56 -07003478 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
3479 int bin = DATA_CONNECTION_NONE;
3480 if (hasData) {
3481 switch (dataType) {
3482 case TelephonyManager.NETWORK_TYPE_EDGE:
3483 bin = DATA_CONNECTION_EDGE;
3484 break;
3485 case TelephonyManager.NETWORK_TYPE_GPRS:
3486 bin = DATA_CONNECTION_GPRS;
3487 break;
3488 case TelephonyManager.NETWORK_TYPE_UMTS:
3489 bin = DATA_CONNECTION_UMTS;
3490 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003491 case TelephonyManager.NETWORK_TYPE_CDMA:
3492 bin = DATA_CONNECTION_CDMA;
3493 break;
3494 case TelephonyManager.NETWORK_TYPE_EVDO_0:
3495 bin = DATA_CONNECTION_EVDO_0;
3496 break;
3497 case TelephonyManager.NETWORK_TYPE_EVDO_A:
3498 bin = DATA_CONNECTION_EVDO_A;
3499 break;
3500 case TelephonyManager.NETWORK_TYPE_1xRTT:
3501 bin = DATA_CONNECTION_1xRTT;
3502 break;
3503 case TelephonyManager.NETWORK_TYPE_HSDPA:
3504 bin = DATA_CONNECTION_HSDPA;
3505 break;
3506 case TelephonyManager.NETWORK_TYPE_HSUPA:
3507 bin = DATA_CONNECTION_HSUPA;
3508 break;
3509 case TelephonyManager.NETWORK_TYPE_HSPA:
3510 bin = DATA_CONNECTION_HSPA;
3511 break;
3512 case TelephonyManager.NETWORK_TYPE_IDEN:
3513 bin = DATA_CONNECTION_IDEN;
3514 break;
3515 case TelephonyManager.NETWORK_TYPE_EVDO_B:
3516 bin = DATA_CONNECTION_EVDO_B;
3517 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07003518 case TelephonyManager.NETWORK_TYPE_LTE:
3519 bin = DATA_CONNECTION_LTE;
3520 break;
3521 case TelephonyManager.NETWORK_TYPE_EHRPD:
3522 bin = DATA_CONNECTION_EHRPD;
3523 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08003524 case TelephonyManager.NETWORK_TYPE_HSPAP:
3525 bin = DATA_CONNECTION_HSPAP;
3526 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07003527 default:
3528 bin = DATA_CONNECTION_OTHER;
3529 break;
3530 }
3531 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003532 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003533 if (mPhoneDataConnectionType != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003534 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003535 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003536 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
3537 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003538 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
3539 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003540 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003541 if (mPhoneDataConnectionType >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003542 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003543 elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003544 }
3545 mPhoneDataConnectionType = bin;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003546 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003547 }
3548 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003549
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003550 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07003551 if (!mWifiOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003552 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003553 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003554 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003555 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
3556 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003557 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003558 mWifiOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003559 mWifiOnTimer.startRunningLocked(elapsedRealtime);
Adam Lesinskia7c90c82015-06-18 14:52:24 -07003560 scheduleSyncExternalWifiStatsLocked("wifi-off");
The Android Open Source Project10592532009-03-18 17:39:46 -07003561 }
3562 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003563
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003564 public void noteWifiOffLocked() {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003565 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003566 final long uptime = SystemClock.uptimeMillis();
The Android Open Source Project10592532009-03-18 17:39:46 -07003567 if (mWifiOn) {
Dianne Hackborn3251b902014-06-20 14:40:53 -07003568 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003569 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
3570 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003571 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003572 mWifiOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003573 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
Adam Lesinskia7c90c82015-06-18 14:52:24 -07003574 scheduleSyncExternalWifiStatsLocked("wifi-on");
The Android Open Source Project10592532009-03-18 17:39:46 -07003575 }
3576 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003577
3578 public void noteAudioOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003579 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003580 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003581 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003582 if (mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003583 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003584 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
3585 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003586 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003587 mAudioOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003588 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003589 mAudioOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003590 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003591 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003592
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003593 public void noteAudioOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003594 if (mAudioOnNesting == 0) {
3595 return;
3596 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003597 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003598 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003599 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003600 if (--mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003601 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003602 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3603 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003604 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003605 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003606 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003607 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003608 }
3609
3610 public void noteVideoOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003611 uid = mapUid(uid);
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();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003614 if (mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003615 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003616 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
3617 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003618 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003619 mVideoOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003620 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003621 mVideoOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003622 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003623 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003624
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003625 public void noteVideoOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003626 if (mVideoOnNesting == 0) {
3627 return;
3628 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003629 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003630 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003631 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003632 if (--mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003633 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003634 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3635 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003636 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003637 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003638 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003639 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003640 }
3641
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003642 public void noteResetAudioLocked() {
3643 if (mAudioOnNesting > 0) {
3644 final long elapsedRealtime = SystemClock.elapsedRealtime();
3645 final long uptime = SystemClock.uptimeMillis();
3646 mAudioOnNesting = 0;
3647 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
3648 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3649 + Integer.toHexString(mHistoryCur.states));
3650 addHistoryRecordLocked(elapsedRealtime, uptime);
3651 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime);
3652 for (int i=0; i<mUidStats.size(); i++) {
3653 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3654 uid.noteResetAudioLocked(elapsedRealtime);
3655 }
3656 }
3657 }
3658
3659 public void noteResetVideoLocked() {
3660 if (mVideoOnNesting > 0) {
3661 final long elapsedRealtime = SystemClock.elapsedRealtime();
3662 final long uptime = SystemClock.uptimeMillis();
3663 mAudioOnNesting = 0;
3664 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
3665 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3666 + Integer.toHexString(mHistoryCur.states));
3667 addHistoryRecordLocked(elapsedRealtime, uptime);
3668 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime);
3669 for (int i=0; i<mUidStats.size(); i++) {
3670 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3671 uid.noteResetVideoLocked(elapsedRealtime);
3672 }
3673 }
3674 }
3675
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003676 public void noteActivityResumedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003677 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003678 getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003679 }
3680
3681 public void noteActivityPausedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003682 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003683 getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003684 }
3685
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003686 public void noteVibratorOnLocked(int uid, long durationMillis) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003687 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003688 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
3689 }
3690
3691 public void noteVibratorOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003692 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003693 getUidStatsLocked(uid).noteVibratorOffLocked();
3694 }
3695
Ruben Brunk6d2c3632015-05-26 17:32:16 -07003696 public void noteFlashlightOnLocked(int uid) {
3697 uid = mapUid(uid);
3698 final long elapsedRealtime = SystemClock.elapsedRealtime();
3699 final long uptime = SystemClock.uptimeMillis();
3700 if (mFlashlightOnNesting++ == 0) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003701 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
3702 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
Ruben Brunk6d2c3632015-05-26 17:32:16 -07003703 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003704 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003705 mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
3706 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07003707 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime);
3708 }
3709
3710 public void noteFlashlightOffLocked(int uid) {
3711 if (mFlashlightOnNesting == 0) {
3712 return;
3713 }
3714 uid = mapUid(uid);
3715 final long elapsedRealtime = SystemClock.elapsedRealtime();
3716 final long uptime = SystemClock.uptimeMillis();
3717 if (--mFlashlightOnNesting == 0) {
3718 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
3719 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
3720 + Integer.toHexString(mHistoryCur.states2));
3721 addHistoryRecordLocked(elapsedRealtime, uptime);
3722 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
3723 }
3724 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime);
3725 }
3726
3727 public void noteCameraOnLocked(int uid) {
3728 uid = mapUid(uid);
3729 final long elapsedRealtime = SystemClock.elapsedRealtime();
3730 final long uptime = SystemClock.uptimeMillis();
3731 if (mCameraOnNesting++ == 0) {
3732 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG;
3733 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: "
3734 + Integer.toHexString(mHistoryCur.states2));
3735 addHistoryRecordLocked(elapsedRealtime, uptime);
3736 mCameraOnTimer.startRunningLocked(elapsedRealtime);
3737 }
3738 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime);
3739 }
3740
3741 public void noteCameraOffLocked(int uid) {
3742 if (mCameraOnNesting == 0) {
3743 return;
3744 }
3745 uid = mapUid(uid);
3746 final long elapsedRealtime = SystemClock.elapsedRealtime();
3747 final long uptime = SystemClock.uptimeMillis();
3748 if (--mCameraOnNesting == 0) {
3749 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
3750 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
3751 + Integer.toHexString(mHistoryCur.states2));
3752 addHistoryRecordLocked(elapsedRealtime, uptime);
3753 mCameraOnTimer.stopRunningLocked(elapsedRealtime);
3754 }
3755 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime);
3756 }
3757
3758 public void noteResetCameraLocked() {
3759 if (mCameraOnNesting > 0) {
3760 final long elapsedRealtime = SystemClock.elapsedRealtime();
3761 final long uptime = SystemClock.uptimeMillis();
3762 mCameraOnNesting = 0;
3763 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
3764 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
3765 + Integer.toHexString(mHistoryCur.states2));
3766 addHistoryRecordLocked(elapsedRealtime, uptime);
3767 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime);
3768 for (int i=0; i<mUidStats.size(); i++) {
3769 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3770 uid.noteResetCameraLocked(elapsedRealtime);
3771 }
3772 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003773 }
3774
Ruben Brunk6d2c3632015-05-26 17:32:16 -07003775 public void noteResetFlashlightLocked() {
3776 if (mFlashlightOnNesting > 0) {
3777 final long elapsedRealtime = SystemClock.elapsedRealtime();
3778 final long uptime = SystemClock.uptimeMillis();
3779 mFlashlightOnNesting = 0;
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003780 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
3781 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
Ruben Brunk6d2c3632015-05-26 17:32:16 -07003782 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003783 addHistoryRecordLocked(elapsedRealtime, uptime);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07003784 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime);
3785 for (int i=0; i<mUidStats.size(); i++) {
3786 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3787 uid.noteResetFlashlightLocked(elapsedRealtime);
3788 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003789 }
3790 }
3791
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003792 public void noteWifiRadioPowerState(int powerState, long timestampNs) {
3793 final long elapsedRealtime = SystemClock.elapsedRealtime();
3794 final long uptime = SystemClock.uptimeMillis();
3795 if (mWifiRadioPowerState != powerState) {
3796 final boolean active =
3797 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
3798 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
3799 if (active) {
3800 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
3801 } else {
3802 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
3803 }
3804 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: "
3805 + Integer.toHexString(mHistoryCur.states));
3806 addHistoryRecordLocked(elapsedRealtime, uptime);
3807 mWifiRadioPowerState = powerState;
3808 }
3809 }
3810
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003811 public void noteWifiRunningLocked(WorkSource ws) {
3812 if (!mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003813 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003814 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003815 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003816 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
3817 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003818 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003819 mGlobalWifiRunning = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003820 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003821 int N = ws.size();
3822 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003823 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003824 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003825 }
Adam Lesinskia7c90c82015-06-18 14:52:24 -07003826 scheduleSyncExternalWifiStatsLocked("wifi-running");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003827 } else {
3828 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003829 }
3830 }
3831
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003832 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
3833 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003834 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003835 int N = oldWs.size();
3836 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003837 int uid = mapUid(oldWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003838 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003839 }
3840 N = newWs.size();
3841 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003842 int uid = mapUid(newWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003843 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003844 }
3845 } else {
3846 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
3847 }
3848 }
3849
3850 public void noteWifiStoppedLocked(WorkSource ws) {
3851 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003852 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003853 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003854 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003855 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
3856 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003857 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003858 mGlobalWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003859 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003860 int N = ws.size();
3861 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003862 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003863 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003864 }
Adam Lesinskia7c90c82015-06-18 14:52:24 -07003865 scheduleSyncExternalWifiStatsLocked("wifi-stopped");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003866 } else {
3867 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003868 }
3869 }
3870
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003871 public void noteWifiStateLocked(int wifiState, String accessPoint) {
3872 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
3873 if (mWifiState != wifiState) {
3874 final long elapsedRealtime = SystemClock.elapsedRealtime();
3875 if (mWifiState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003876 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003877 }
3878 mWifiState = wifiState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003879 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
Adam Lesinskia7c90c82015-06-18 14:52:24 -07003880 scheduleSyncExternalWifiStatsLocked("wifi-state");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003881 }
3882 }
3883
Dianne Hackborn3251b902014-06-20 14:40:53 -07003884 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
3885 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
3886 if (mWifiSupplState != supplState) {
3887 final long elapsedRealtime = SystemClock.elapsedRealtime();
3888 final long uptime = SystemClock.uptimeMillis();
3889 if (mWifiSupplState >= 0) {
3890 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime);
3891 }
3892 mWifiSupplState = supplState;
3893 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime);
3894 mHistoryCur.states2 =
3895 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
3896 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
3897 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
3898 + Integer.toHexString(mHistoryCur.states2));
3899 addHistoryRecordLocked(elapsedRealtime, uptime);
3900 }
3901 }
3902
3903 void stopAllWifiSignalStrengthTimersLocked(int except) {
3904 final long elapsedRealtime = SystemClock.elapsedRealtime();
3905 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
3906 if (i == except) {
3907 continue;
3908 }
3909 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) {
3910 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
3911 }
3912 }
3913 }
3914
3915 public void noteWifiRssiChangedLocked(int newRssi) {
3916 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
3917 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
3918 if (mWifiSignalStrengthBin != strengthBin) {
3919 final long elapsedRealtime = SystemClock.elapsedRealtime();
3920 final long uptime = SystemClock.uptimeMillis();
3921 if (mWifiSignalStrengthBin >= 0) {
3922 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked(
3923 elapsedRealtime);
3924 }
3925 if (strengthBin >= 0) {
3926 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
3927 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
3928 }
3929 mHistoryCur.states2 =
3930 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
3931 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
3932 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
3933 + Integer.toHexString(mHistoryCur.states2));
3934 addHistoryRecordLocked(elapsedRealtime, uptime);
3935 } else {
3936 stopAllWifiSignalStrengthTimersLocked(-1);
3937 }
3938 mWifiSignalStrengthBin = strengthBin;
3939 }
3940 }
3941
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003942 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003943
The Android Open Source Project10592532009-03-18 17:39:46 -07003944 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003945 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003946 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003947 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003948 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003949 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003950 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
3951 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003952 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003953 }
3954 mWifiFullLockNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003955 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003956 }
3957
3958 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003959 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003960 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003961 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003962 mWifiFullLockNesting--;
3963 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003964 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003965 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
3966 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003967 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003968 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003969 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003970 }
3971
Nick Pelly6ccaa542012-06-15 15:22:47 -07003972 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003973
Nick Pelly6ccaa542012-06-15 15:22:47 -07003974 public void noteWifiScanStartedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003975 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003976 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003977 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003978 if (mWifiScanNesting == 0) {
3979 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
3980 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003981 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003982 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003983 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003984 mWifiScanNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003985 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003986 }
3987
Nick Pelly6ccaa542012-06-15 15:22:47 -07003988 public void noteWifiScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003989 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003990 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003991 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003992 mWifiScanNesting--;
3993 if (mWifiScanNesting == 0) {
3994 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
3995 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003996 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003997 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003998 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003999 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07004000 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004001
Robert Greenwalta029ea12013-09-25 16:38:12 -07004002 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004003 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004004 final long elapsedRealtime = SystemClock.elapsedRealtime();
4005 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004006 }
4007
4008 public void noteWifiBatchedScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004009 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004010 final long elapsedRealtime = SystemClock.elapsedRealtime();
4011 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004012 }
4013
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004014 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004015
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004016 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004017 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004018 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07004019 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004020 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004021 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004022 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
4023 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004024 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004025 }
4026 mWifiMulticastNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004027 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004028 }
4029
4030 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004031 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004032 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07004033 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004034 mWifiMulticastNesting--;
4035 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004036 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004037 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
4038 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004039 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004040 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004041 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004042 }
4043
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004044 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
4045 int N = ws.size();
4046 for (int i=0; i<N; i++) {
4047 noteFullWifiLockAcquiredLocked(ws.get(i));
4048 }
4049 }
4050
4051 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
4052 int N = ws.size();
4053 for (int i=0; i<N; i++) {
4054 noteFullWifiLockReleasedLocked(ws.get(i));
4055 }
4056 }
4057
Nick Pelly6ccaa542012-06-15 15:22:47 -07004058 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004059 int N = ws.size();
4060 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004061 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004062 }
4063 }
4064
Nick Pelly6ccaa542012-06-15 15:22:47 -07004065 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004066 int N = ws.size();
4067 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004068 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004069 }
4070 }
4071
Robert Greenwalta029ea12013-09-25 16:38:12 -07004072 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
4073 int N = ws.size();
4074 for (int i=0; i<N; i++) {
4075 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
4076 }
4077 }
4078
4079 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
4080 int N = ws.size();
4081 for (int i=0; i<N; i++) {
4082 noteWifiBatchedScanStoppedLocked(ws.get(i));
4083 }
4084 }
4085
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004086 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
4087 int N = ws.size();
4088 for (int i=0; i<N; i++) {
4089 noteWifiMulticastEnabledLocked(ws.get(i));
4090 }
4091 }
4092
4093 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
4094 int N = ws.size();
4095 for (int i=0; i<N; i++) {
4096 noteWifiMulticastDisabledLocked(ws.get(i));
4097 }
4098 }
4099
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004100 private static String[] includeInStringArray(String[] array, String str) {
4101 if (ArrayUtils.indexOf(array, str) >= 0) {
4102 return array;
4103 }
4104 String[] newArray = new String[array.length+1];
4105 System.arraycopy(array, 0, newArray, 0, array.length);
4106 newArray[array.length] = str;
4107 return newArray;
4108 }
4109
4110 private static String[] excludeFromStringArray(String[] array, String str) {
4111 int index = ArrayUtils.indexOf(array, str);
4112 if (index >= 0) {
4113 String[] newArray = new String[array.length-1];
4114 if (index > 0) {
4115 System.arraycopy(array, 0, newArray, 0, index);
4116 }
4117 if (index < array.length-1) {
4118 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
4119 }
4120 return newArray;
4121 }
4122 return array;
4123 }
4124
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004125 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07004126 if (TextUtils.isEmpty(iface)) return;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004127 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004128 mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
4129 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004130 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004131 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
4132 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004133 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004134 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004135 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
4136 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004137 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004138 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
4139 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004140 }
4141 }
4142
4143 public void noteNetworkStatsEnabledLocked() {
4144 // During device boot, qtaguid isn't enabled until after the inital
4145 // loading of battery stats. Now that they're enabled, take our initial
4146 // snapshot for future delta calculation.
Adam Lesinskie08af192015-03-25 16:42:59 -07004147 final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
4148 updateMobileRadioStateLocked(elapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07004149 updateWifiStateLocked(null);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004150 }
4151
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004152 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
4153 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004154 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004155
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004156 @Override public int getScreenOnCount(int which) {
4157 return mScreenOnTimer.getCountLocked(which);
4158 }
4159
Dianne Hackborn617f8772009-03-31 15:04:46 -07004160 @Override public long getScreenBrightnessTime(int brightnessBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004161 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004162 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004163 elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004164 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004165
Jeff Browne95c3cd2014-05-02 16:59:26 -07004166 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
4167 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004168 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004169
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004170 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) {
4171 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004172 }
4173
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004174 @Override public int getPowerSaveModeEnabledCount(int which) {
4175 return mPowerSaveModeEnabledTimer.getCountLocked(which);
4176 }
4177
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004178 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs,
4179 int which) {
4180 switch (mode) {
4181 case DEVICE_IDLE_MODE_LIGHT:
4182 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4183 case DEVICE_IDLE_MODE_FULL:
4184 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4185 }
4186 return 0;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004187 }
4188
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004189 @Override public int getDeviceIdleModeCount(int mode, int which) {
4190 switch (mode) {
4191 case DEVICE_IDLE_MODE_LIGHT:
4192 return mDeviceIdleModeLightTimer.getCountLocked(which);
4193 case DEVICE_IDLE_MODE_FULL:
4194 return mDeviceIdleModeFullTimer.getCountLocked(which);
4195 }
4196 return 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004197 }
4198
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004199 @Override public long getLongestDeviceIdleModeTime(int mode) {
4200 switch (mode) {
4201 case DEVICE_IDLE_MODE_LIGHT:
4202 return mLongestLightIdleTime;
4203 case DEVICE_IDLE_MODE_FULL:
4204 return mLongestFullIdleTime;
4205 }
4206 return 0;
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004207 }
4208
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004209 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) {
4210 switch (mode) {
4211 case DEVICE_IDLE_MODE_LIGHT:
4212 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4213 case DEVICE_IDLE_MODE_FULL:
4214 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4215 }
4216 return 0;
4217 }
4218
4219 @Override public int getDeviceIdlingCount(int mode, int which) {
4220 switch (mode) {
4221 case DEVICE_IDLE_MODE_LIGHT:
4222 return mDeviceLightIdlingTimer.getCountLocked(which);
4223 case DEVICE_IDLE_MODE_FULL:
4224 return mDeviceIdlingTimer.getCountLocked(which);
4225 }
4226 return 0;
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004227 }
4228
Dianne Hackborn1e01d162014-12-04 17:46:42 -08004229 @Override public int getNumConnectivityChange(int which) {
4230 int val = mNumConnectivityChange;
4231 if (which == STATS_CURRENT) {
4232 val -= mLoadedNumConnectivityChange;
4233 } else if (which == STATS_SINCE_UNPLUGGED) {
4234 val -= mUnpluggedNumConnectivityChange;
4235 }
4236 return val;
4237 }
4238
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004239 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
4240 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004242
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004243 @Override public int getPhoneOnCount(int which) {
4244 return mPhoneOnTimer.getCountLocked(which);
4245 }
4246
Dianne Hackborn627bba72009-03-24 22:32:56 -07004247 @Override public long getPhoneSignalStrengthTime(int strengthBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004248 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004249 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004250 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004251 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004252
4253 @Override public long getPhoneSignalScanningTime(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004254 long elapsedRealtimeUs, int which) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07004255 return mPhoneSignalScanningTimer.getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004256 elapsedRealtimeUs, which);
Amith Yamasanif37447b2009-10-08 18:28:01 -07004257 }
4258
Catherine Liufb900812012-07-17 14:12:56 -05004259 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
4260 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004261 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004262
Dianne Hackborn627bba72009-03-24 22:32:56 -07004263 @Override public long getPhoneDataConnectionTime(int dataType,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004264 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004265 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004266 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004267 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004268
Dianne Hackborn617f8772009-03-31 15:04:46 -07004269 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004270 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004271 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004272
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004273 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
4274 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004275 }
4276
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004277 @Override public int getMobileRadioActiveCount(int which) {
4278 return mMobileRadioActiveTimer.getCountLocked(which);
4279 }
4280
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004281 @Override public long getMobileRadioActiveAdjustedTime(int which) {
4282 return mMobileRadioActiveAdjustedTime.getCountLocked(which);
4283 }
4284
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004285 @Override public long getMobileRadioActiveUnknownTime(int which) {
4286 return mMobileRadioActiveUnknownTime.getCountLocked(which);
4287 }
4288
4289 @Override public int getMobileRadioActiveUnknownCount(int which) {
4290 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
4291 }
4292
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004293 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
4294 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004295 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004296
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004297 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
4298 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07004299 }
4300
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004301 @Override public long getWifiStateTime(int wifiState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004302 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004303 return mWifiStateTimer[wifiState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004304 elapsedRealtimeUs, which);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004305 }
4306
4307 @Override public int getWifiStateCount(int wifiState, int which) {
4308 return mWifiStateTimer[wifiState].getCountLocked(which);
4309 }
4310
Dianne Hackborn3251b902014-06-20 14:40:53 -07004311 @Override public long getWifiSupplStateTime(int state,
4312 long elapsedRealtimeUs, int which) {
4313 return mWifiSupplStateTimer[state].getTotalTimeLocked(
4314 elapsedRealtimeUs, which);
4315 }
4316
4317 @Override public int getWifiSupplStateCount(int state, int which) {
4318 return mWifiSupplStateTimer[state].getCountLocked(which);
4319 }
4320
4321 @Override public long getWifiSignalStrengthTime(int strengthBin,
4322 long elapsedRealtimeUs, int which) {
4323 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
4324 elapsedRealtimeUs, which);
4325 }
4326
4327 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) {
4328 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which);
4329 }
4330
Adam Lesinski17390762015-04-10 13:17:47 -07004331 @Override public boolean hasBluetoothActivityReporting() {
4332 return mHasBluetoothEnergyReporting;
4333 }
4334
Adam Lesinski33dac552015-03-09 15:24:48 -07004335 @Override public long getBluetoothControllerActivity(int type, int which) {
4336 if (type >= 0 && type < mBluetoothActivityCounters.length) {
4337 return mBluetoothActivityCounters[type].getCountLocked(which);
4338 }
4339 return 0;
4340 }
4341
Adam Lesinski17390762015-04-10 13:17:47 -07004342 @Override public boolean hasWifiActivityReporting() {
4343 return mHasWifiEnergyReporting;
4344 }
4345
Adam Lesinski33dac552015-03-09 15:24:48 -07004346 @Override public long getWifiControllerActivity(int type, int which) {
4347 if (type >= 0 && type < mWifiActivityCounters.length) {
4348 return mWifiActivityCounters[type].getCountLocked(which);
4349 }
4350 return 0;
4351 }
4352
Ruben Brunk5b1308f2015-06-03 18:49:27 -07004353 @Override
4354 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004355 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4356 }
4357
Ruben Brunk5b1308f2015-06-03 18:49:27 -07004358 @Override
4359 public long getFlashlightOnCount(int which) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004360 return mFlashlightOnTimer.getCountLocked(which);
4361 }
4362
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004363 @Override
Ruben Brunk5b1308f2015-06-03 18:49:27 -07004364 public long getCameraOnTime(long elapsedRealtimeUs, int which) {
4365 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4366 }
4367
4368 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004369 public long getNetworkActivityBytes(int type, int which) {
4370 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
4371 return mNetworkByteActivityCounters[type].getCountLocked(which);
4372 } else {
4373 return 0;
4374 }
4375 }
4376
4377 @Override
4378 public long getNetworkActivityPackets(int type, int which) {
4379 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
4380 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004381 } else {
4382 return 0;
4383 }
4384 }
4385
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08004386 @Override public long getStartClockTime() {
Dianne Hackbornd48954f2015-07-22 17:20:33 -07004387 final long currentTime = System.currentTimeMillis();
4388 if (ensureStartClockTime(currentTime)) {
4389 recordCurrentTimeChangeLocked(currentTime, SystemClock.elapsedRealtime(),
4390 SystemClock.uptimeMillis());
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07004391 }
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08004392 return mStartClockTime;
4393 }
4394
Dianne Hackborncd0e3352014-08-07 17:08:09 -07004395 @Override public String getStartPlatformVersion() {
4396 return mStartPlatformVersion;
4397 }
4398
4399 @Override public String getEndPlatformVersion() {
4400 return mEndPlatformVersion;
4401 }
4402
4403 @Override public int getParcelVersion() {
4404 return VERSION;
4405 }
4406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004407 @Override public boolean getIsOnBattery() {
4408 return mOnBattery;
4409 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
4412 return mUidStats;
4413 }
4414
4415 /**
4416 * The statistics associated with a particular uid.
4417 */
4418 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004421
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004422 boolean mWifiRunning;
4423 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004424
The Android Open Source Project10592532009-03-18 17:39:46 -07004425 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07004426 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004427
Nick Pelly6ccaa542012-06-15 15:22:47 -07004428 boolean mWifiScanStarted;
4429 StopwatchTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004430
Dianne Hackborn61659e52014-07-09 16:13:01 -07004431 static final int NO_BATCHED_SCAN_STARTED = -1;
Robert Greenwalta029ea12013-09-25 16:38:12 -07004432 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4433 StopwatchTimer[] mWifiBatchedScanTimer;
4434
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004435 boolean mWifiMulticastEnabled;
4436 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004437
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004438 StopwatchTimer mAudioTurnedOnTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004439 StopwatchTimer mVideoTurnedOnTimer;
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004440 StopwatchTimer mFlashlightTurnedOnTimer;
4441 StopwatchTimer mCameraTurnedOnTimer;
4442
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004443
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004444 StopwatchTimer mForegroundActivityTimer;
4445
Dianne Hackborna8d10942015-11-19 17:55:19 -08004446 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
Dianne Hackborn61659e52014-07-09 16:13:01 -07004447 StopwatchTimer[] mProcessStateTimer;
4448
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004449 BatchTimer mVibratorOnTimer;
4450
Dianne Hackborn617f8772009-03-31 15:04:46 -07004451 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004452
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004453 LongSamplingCounter[] mNetworkByteActivityCounters;
4454 LongSamplingCounter[] mNetworkPacketActivityCounters;
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004455 LongSamplingCounter mMobileRadioActiveTime;
4456 LongSamplingCounter mMobileRadioActiveCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004458 /**
Adam Lesinskie08af192015-03-25 16:42:59 -07004459 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode.
4460 */
4461 LongSamplingCounter[] mWifiControllerTime =
4462 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
4463
4464 /**
4465 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode.
4466 */
4467 LongSamplingCounter[] mBluetoothControllerTime =
4468 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
4469
4470 /**
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08004471 * The CPU times we had at the last history details update.
4472 */
4473 long mLastStepUserTime;
4474 long mLastStepSystemTime;
4475 long mCurStepUserTime;
4476 long mCurStepSystemTime;
4477
Adam Lesinski06af1fa2015-05-05 17:35:35 -07004478 LongSamplingCounter mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
4479 LongSamplingCounter mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07004480 LongSamplingCounter mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase);
Adam Lesinski6832f392015-09-05 18:05:40 -07004481 LongSamplingCounter[][] mCpuClusterSpeed;
Adam Lesinski06af1fa2015-05-05 17:35:35 -07004482
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08004483 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 * The statistics we have collected for this uid's wake locks.
4485 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004486 final OverflowArrayMap<Wakelock> mWakelockStats = new OverflowArrayMap<Wakelock>() {
4487 @Override public Wakelock instantiateObject() { return new Wakelock(); }
4488 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004489
4490 /**
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004491 * The statistics we have collected for this uid's syncs.
4492 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004493 final OverflowArrayMap<StopwatchTimer> mSyncStats = new OverflowArrayMap<StopwatchTimer>() {
4494 @Override public StopwatchTimer instantiateObject() {
4495 return new StopwatchTimer(Uid.this, SYNC, null, mOnBatteryTimeBase);
4496 }
4497 };
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004498
4499 /**
4500 * The statistics we have collected for this uid's jobs.
4501 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004502 final OverflowArrayMap<StopwatchTimer> mJobStats = new OverflowArrayMap<StopwatchTimer>() {
4503 @Override public StopwatchTimer instantiateObject() {
4504 return new StopwatchTimer(Uid.this, JOB, null, mOnBatteryTimeBase);
4505 }
4506 };
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004507
4508 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 * The statistics we have collected for this uid's sensor activations.
4510 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004511 final SparseArray<Sensor> mSensorStats = new SparseArray<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512
4513 /**
4514 * The statistics we have collected for this uid's processes.
4515 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004516 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004517
4518 /**
4519 * The statistics we have collected for this uid's processes.
4520 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004521 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004522
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004523 /**
4524 * The transient wake stats we have collected for this uid's pids.
4525 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004526 final SparseArray<Pid> mPids = new SparseArray<>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004528 public Uid(int uid) {
4529 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004530 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004531 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004532 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004533 mFullWifiLockTimers, mOnBatteryTimeBase);
Nick Pelly6ccaa542012-06-15 15:22:47 -07004534 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004535 mWifiScanTimers, mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004536 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004537 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004538 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn61659e52014-07-09 16:13:01 -07004539 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 }
4541
4542 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004543 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004544 return mWakelockStats.getMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004545 }
4546
4547 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004548 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004549 return mSyncStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004550 }
4551
4552 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004553 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004554 return mJobStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004555 }
4556
4557 @Override
Dianne Hackborn61659e52014-07-09 16:13:01 -07004558 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 return mSensorStats;
4560 }
4561
4562 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004563 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004564 return mProcessStats;
4565 }
4566
4567 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004568 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004569 return mPackageStats;
4570 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004571
4572 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 public int getUid() {
4574 return mUid;
4575 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004576
4577 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004578 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004579 if (!mWifiRunning) {
4580 mWifiRunning = true;
4581 if (mWifiRunningTimer == null) {
4582 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004583 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004584 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004585 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004586 }
4587 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004588
Dianne Hackborn617f8772009-03-31 15:04:46 -07004589 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004590 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004591 if (mWifiRunning) {
4592 mWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004593 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004594 }
4595 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004596
Dianne Hackborn617f8772009-03-31 15:04:46 -07004597 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004598 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07004599 if (!mFullWifiLockOut) {
4600 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004601 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004602 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004603 mFullWifiLockTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004604 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004605 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004606 }
4607 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004608
The Android Open Source Project10592532009-03-18 17:39:46 -07004609 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004610 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07004611 if (mFullWifiLockOut) {
4612 mFullWifiLockOut = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004613 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004614 }
4615 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004616
The Android Open Source Project10592532009-03-18 17:39:46 -07004617 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004618 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004619 if (!mWifiScanStarted) {
4620 mWifiScanStarted = true;
4621 if (mWifiScanTimer == null) {
4622 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004623 mWifiScanTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004624 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004625 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004626 }
4627 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004628
The Android Open Source Project10592532009-03-18 17:39:46 -07004629 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004630 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004631 if (mWifiScanStarted) {
4632 mWifiScanStarted = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004633 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004634 }
4635 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004636
4637 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004638 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004639 int bin = 0;
Navtej Singh Mann3c0ce5c2015-06-11 16:53:11 -07004640 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004641 csph = csph >> 3;
4642 bin++;
4643 }
4644
4645 if (mWifiBatchedScanBinStarted == bin) return;
4646
4647 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
4648 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004649 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004650 }
4651 mWifiBatchedScanBinStarted = bin;
4652 if (mWifiBatchedScanTimer[bin] == null) {
4653 makeWifiBatchedScanBin(bin, null);
4654 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004655 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004656 }
4657
4658 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004659 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004660 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
4661 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004662 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004663 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4664 }
4665 }
4666
4667 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004668 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004669 if (!mWifiMulticastEnabled) {
4670 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004671 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004672 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004673 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004674 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004675 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004676 }
4677 }
4678
4679 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004680 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004681 if (mWifiMulticastEnabled) {
4682 mWifiMulticastEnabled = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004683 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004684 }
4685 }
4686
Adam Lesinskie08af192015-03-25 16:42:59 -07004687 public void noteWifiControllerActivityLocked(int type, long timeMs) {
4688 if (mWifiControllerTime[type] == null) {
4689 mWifiControllerTime[type] = new LongSamplingCounter(mOnBatteryTimeBase);
4690 }
4691 mWifiControllerTime[type].addCountLocked(timeMs);
4692 }
4693
Adam Lesinski50e47602015-12-04 17:04:54 -08004694 public void noteBluetoothControllerActivityLocked(int type, long timeMs) {
4695 if (mBluetoothControllerTime[type] == null) {
4696 mBluetoothControllerTime[type] = new LongSamplingCounter(mOnBatteryTimeBase);
4697 }
4698 mBluetoothControllerTime[type].addCountLocked(timeMs);
4699 }
4700
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004701 public StopwatchTimer createAudioTurnedOnTimerLocked() {
4702 if (mAudioTurnedOnTimer == null) {
4703 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004704 mAudioTurnedOnTimers, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004705 }
4706 return mAudioTurnedOnTimer;
4707 }
4708
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004709 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004710 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4711 }
4712
4713 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
4714 if (mAudioTurnedOnTimer != null) {
4715 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004716 }
4717 }
4718
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004719 public void noteResetAudioLocked(long elapsedRealtimeMs) {
4720 if (mAudioTurnedOnTimer != null) {
4721 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004722 }
4723 }
4724
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004725 public StopwatchTimer createVideoTurnedOnTimerLocked() {
4726 if (mVideoTurnedOnTimer == null) {
4727 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004728 mVideoTurnedOnTimers, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004729 }
4730 return mVideoTurnedOnTimer;
4731 }
4732
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004733 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004734 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4735 }
4736
4737 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
4738 if (mVideoTurnedOnTimer != null) {
4739 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004740 }
4741 }
4742
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004743 public void noteResetVideoLocked(long elapsedRealtimeMs) {
4744 if (mVideoTurnedOnTimer != null) {
4745 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004746 }
4747 }
4748
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004749 public StopwatchTimer createFlashlightTurnedOnTimerLocked() {
4750 if (mFlashlightTurnedOnTimer == null) {
4751 mFlashlightTurnedOnTimer = new StopwatchTimer(Uid.this, FLASHLIGHT_TURNED_ON,
4752 mFlashlightTurnedOnTimers, mOnBatteryTimeBase);
4753 }
4754 return mFlashlightTurnedOnTimer;
4755 }
4756
4757 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) {
4758 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4759 }
4760
4761 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) {
4762 if (mFlashlightTurnedOnTimer != null) {
4763 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
4764 }
4765 }
4766
4767 public void noteResetFlashlightLocked(long elapsedRealtimeMs) {
4768 if (mFlashlightTurnedOnTimer != null) {
4769 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
4770 }
4771 }
4772
4773 public StopwatchTimer createCameraTurnedOnTimerLocked() {
4774 if (mCameraTurnedOnTimer == null) {
4775 mCameraTurnedOnTimer = new StopwatchTimer(Uid.this, CAMERA_TURNED_ON,
4776 mCameraTurnedOnTimers, mOnBatteryTimeBase);
4777 }
4778 return mCameraTurnedOnTimer;
4779 }
4780
4781 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) {
4782 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4783 }
4784
4785 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) {
4786 if (mCameraTurnedOnTimer != null) {
4787 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
4788 }
4789 }
4790
4791 public void noteResetCameraLocked(long elapsedRealtimeMs) {
4792 if (mCameraTurnedOnTimer != null) {
4793 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
4794 }
4795 }
4796
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004797 public StopwatchTimer createForegroundActivityTimerLocked() {
4798 if (mForegroundActivityTimer == null) {
4799 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004800 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004801 }
4802 return mForegroundActivityTimer;
4803 }
4804
4805 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004806 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004807 // We always start, since we want multiple foreground PIDs to nest
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004808 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004809 }
4810
4811 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004812 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004813 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004814 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004815 }
4816 }
4817
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004818 public BatchTimer createVibratorOnTimerLocked() {
4819 if (mVibratorOnTimer == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004820 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004821 }
4822 return mVibratorOnTimer;
4823 }
4824
4825 public void noteVibratorOnLocked(long durationMillis) {
4826 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
4827 }
4828
4829 public void noteVibratorOffLocked() {
4830 if (mVibratorOnTimer != null) {
4831 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004832 }
4833 }
4834
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004835 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004836 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004837 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004838 return 0;
4839 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004840 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004841 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004842
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004843 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004844 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004845 if (mFullWifiLockTimer == null) {
4846 return 0;
4847 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004848 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004849 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004850
4851 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004852 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004853 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004854 return 0;
4855 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004856 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004857 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004858
4859 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07004860 public int getWifiScanCount(int which) {
4861 if (mWifiScanTimer == null) {
4862 return 0;
4863 }
4864 return mWifiScanTimer.getCountLocked(which);
4865 }
4866
4867 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004868 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004869 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
4870 if (mWifiBatchedScanTimer[csphBin] == null) {
4871 return 0;
4872 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004873 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004874 }
4875
4876 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07004877 public int getWifiBatchedScanCount(int csphBin, int which) {
4878 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
4879 if (mWifiBatchedScanTimer[csphBin] == null) {
4880 return 0;
4881 }
4882 return mWifiBatchedScanTimer[csphBin].getCountLocked(which);
4883 }
4884
4885 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004886 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004887 if (mWifiMulticastTimer == null) {
4888 return 0;
4889 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004890 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004891 }
4892
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004893 @Override
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004894 public Timer getAudioTurnedOnTimer() {
4895 return mAudioTurnedOnTimer;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004896 }
4897
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004898 @Override
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004899 public Timer getVideoTurnedOnTimer() {
4900 return mVideoTurnedOnTimer;
4901 }
4902
4903 @Override
4904 public Timer getFlashlightTurnedOnTimer() {
4905 return mFlashlightTurnedOnTimer;
4906 }
4907
4908 @Override
4909 public Timer getCameraTurnedOnTimer() {
4910 return mCameraTurnedOnTimer;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004911 }
4912
Dianne Hackborn617f8772009-03-31 15:04:46 -07004913 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004914 public Timer getForegroundActivityTimer() {
4915 return mForegroundActivityTimer;
4916 }
4917
Dianne Hackborn61659e52014-07-09 16:13:01 -07004918 void makeProcessState(int i, Parcel in) {
4919 if (i < 0 || i >= NUM_PROCESS_STATE) return;
4920
4921 if (in == null) {
4922 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null,
4923 mOnBatteryTimeBase);
4924 } else {
4925 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null,
4926 mOnBatteryTimeBase, in);
4927 }
4928 }
4929
4930 @Override
4931 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) {
4932 if (state < 0 || state >= NUM_PROCESS_STATE) return 0;
4933 if (mProcessStateTimer[state] == null) {
4934 return 0;
4935 }
4936 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which);
4937 }
4938
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004939 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004940 public Timer getVibratorOnTimer() {
4941 return mVibratorOnTimer;
4942 }
4943
4944 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07004945 public void noteUserActivityLocked(int type) {
4946 if (mUserActivityCounters == null) {
4947 initUserActivityLocked();
4948 }
Jeff Browndf693de2012-07-27 12:03:38 -07004949 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
4950 mUserActivityCounters[type].stepAtomic();
4951 } else {
4952 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
4953 new Throwable());
4954 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07004955 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004956
Dianne Hackborn617f8772009-03-31 15:04:46 -07004957 @Override
4958 public boolean hasUserActivity() {
4959 return mUserActivityCounters != null;
4960 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004961
Dianne Hackborn617f8772009-03-31 15:04:46 -07004962 @Override
4963 public int getUserActivityCount(int type, int which) {
4964 if (mUserActivityCounters == null) {
4965 return 0;
4966 }
Evan Millarc64edde2009-04-18 12:26:32 -07004967 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004968 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004969
Robert Greenwalta029ea12013-09-25 16:38:12 -07004970 void makeWifiBatchedScanBin(int i, Parcel in) {
4971 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
4972
4973 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i);
4974 if (collected == null) {
4975 collected = new ArrayList<StopwatchTimer>();
4976 mWifiBatchedScanTimers.put(i, collected);
4977 }
4978 if (in == null) {
4979 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004980 mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004981 } else {
4982 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004983 mOnBatteryTimeBase, in);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004984 }
4985 }
4986
4987
Dianne Hackborn617f8772009-03-31 15:04:46 -07004988 void initUserActivityLocked() {
4989 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
4990 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004991 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004992 }
4993 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004994
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004995 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
4996 if (mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004997 initNetworkActivityLocked();
4998 }
4999 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005000 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
5001 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005002 } else {
5003 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
5004 new Throwable());
5005 }
5006 }
5007
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005008 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
5009 if (mNetworkByteActivityCounters == null) {
5010 initNetworkActivityLocked();
5011 }
5012 mMobileRadioActiveTime.addCountLocked(batteryUptime);
5013 mMobileRadioActiveCount.addCountLocked(1);
5014 }
5015
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005016 @Override
5017 public boolean hasNetworkActivity() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005018 return mNetworkByteActivityCounters != null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005019 }
5020
5021 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005022 public long getNetworkActivityBytes(int type, int which) {
5023 if (mNetworkByteActivityCounters != null && type >= 0
5024 && type < mNetworkByteActivityCounters.length) {
5025 return mNetworkByteActivityCounters[type].getCountLocked(which);
5026 } else {
5027 return 0;
5028 }
5029 }
5030
5031 @Override
5032 public long getNetworkActivityPackets(int type, int which) {
5033 if (mNetworkPacketActivityCounters != null && type >= 0
5034 && type < mNetworkPacketActivityCounters.length) {
5035 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005036 } else {
5037 return 0;
5038 }
5039 }
5040
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005041 @Override
5042 public long getMobileRadioActiveTime(int which) {
5043 return mMobileRadioActiveTime != null
5044 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
5045 }
5046
5047 @Override
5048 public int getMobileRadioActiveCount(int which) {
5049 return mMobileRadioActiveCount != null
5050 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
5051 }
5052
Adam Lesinskie08af192015-03-25 16:42:59 -07005053 @Override
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005054 public long getUserCpuTimeUs(int which) {
5055 return mUserCpuTime.getCountLocked(which);
5056 }
5057
5058 @Override
5059 public long getSystemCpuTimeUs(int which) {
5060 return mSystemCpuTime.getCountLocked(which);
5061 }
5062
5063 @Override
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07005064 public long getCpuPowerMaUs(int which) {
5065 return mCpuPower.getCountLocked(which);
5066 }
5067
5068 @Override
Adam Lesinski6832f392015-09-05 18:05:40 -07005069 public long getTimeAtCpuSpeed(int cluster, int step, int which) {
5070 if (mCpuClusterSpeed != null) {
5071 if (cluster >= 0 && cluster < mCpuClusterSpeed.length) {
5072 final LongSamplingCounter[] cpuSpeeds = mCpuClusterSpeed[cluster];
5073 if (cpuSpeeds != null) {
5074 if (step >= 0 && step < cpuSpeeds.length) {
5075 final LongSamplingCounter c = cpuSpeeds[step];
5076 if (c != null) {
5077 return c.getCountLocked(which);
5078 }
5079 }
5080 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005081 }
5082 }
5083 return 0;
5084 }
5085
5086 @Override
Adam Lesinskie08af192015-03-25 16:42:59 -07005087 public long getWifiControllerActivity(int type, int which) {
5088 if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES &&
5089 mWifiControllerTime[type] != null) {
5090 return mWifiControllerTime[type].getCountLocked(which);
5091 }
5092 return 0;
5093 }
5094
Adam Lesinski50e47602015-12-04 17:04:54 -08005095 @Override
5096 public long getBluetoothControllerActivity(int type, int which) {
5097 if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES &&
5098 mBluetoothControllerTime[type] != null) {
5099 return mBluetoothControllerTime[type].getCountLocked(which);
5100 }
5101 return 0;
5102 }
5103
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005104 void initNetworkActivityLocked() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005105 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
5106 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005107 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005108 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
5109 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005110 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005111 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase);
5112 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005113 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005114
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005115 /**
5116 * Clear all stats for this uid. Returns true if the uid is completely
5117 * inactive so can be dropped.
5118 */
5119 boolean reset() {
5120 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005121
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005122 if (mWifiRunningTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005123 active |= !mWifiRunningTimer.reset(false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005124 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005125 }
5126 if (mFullWifiLockTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005127 active |= !mFullWifiLockTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005128 active |= mFullWifiLockOut;
5129 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005130 if (mWifiScanTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005131 active |= !mWifiScanTimer.reset(false);
Nick Pelly6ccaa542012-06-15 15:22:47 -07005132 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005133 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005134 if (mWifiBatchedScanTimer != null) {
5135 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5136 if (mWifiBatchedScanTimer[i] != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005137 active |= !mWifiBatchedScanTimer[i].reset(false);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005138 }
5139 }
5140 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
5141 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005142 if (mWifiMulticastTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005143 active |= !mWifiMulticastTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005144 active |= mWifiMulticastEnabled;
5145 }
5146 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005147 active |= !mAudioTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005148 }
5149 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005150 active |= !mVideoTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005151 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07005152 if (mFlashlightTurnedOnTimer != null) {
5153 active |= !mFlashlightTurnedOnTimer.reset(false);
5154 }
5155 if (mCameraTurnedOnTimer != null) {
5156 active |= !mCameraTurnedOnTimer.reset(false);
5157 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005158 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005159 active |= !mForegroundActivityTimer.reset(false);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005160 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005161 if (mProcessStateTimer != null) {
5162 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5163 if (mProcessStateTimer[i] != null) {
5164 active |= !mProcessStateTimer[i].reset(false);
5165 }
5166 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08005167 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005168 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005169 if (mVibratorOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005170 if (mVibratorOnTimer.reset(false)) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005171 mVibratorOnTimer.detach();
5172 mVibratorOnTimer = null;
5173 } else {
5174 active = true;
5175 }
5176 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005177
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005178 if (mUserActivityCounters != null) {
5179 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5180 mUserActivityCounters[i].reset(false);
5181 }
5182 }
5183
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005184 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005185 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005186 mNetworkByteActivityCounters[i].reset(false);
5187 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005188 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005189 mMobileRadioActiveTime.reset(false);
5190 mMobileRadioActiveCount.reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005191 }
5192
Adam Lesinskie08af192015-03-25 16:42:59 -07005193 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5194 if (mWifiControllerTime[i] != null) {
5195 mWifiControllerTime[i].reset(false);
5196 }
5197
5198 if (mBluetoothControllerTime[i] != null) {
5199 mBluetoothControllerTime[i].reset(false);
5200 }
5201 }
5202
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005203 mUserCpuTime.reset(false);
5204 mSystemCpuTime.reset(false);
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07005205 mCpuPower.reset(false);
Adam Lesinski6832f392015-09-05 18:05:40 -07005206
5207 if (mCpuClusterSpeed != null) {
5208 for (LongSamplingCounter[] speeds : mCpuClusterSpeed) {
5209 if (speeds != null) {
5210 for (LongSamplingCounter speed : speeds) {
5211 if (speed != null) {
5212 speed.reset(false);
5213 }
5214 }
5215 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005216 }
5217 }
5218
Dianne Hackbornd953c532014-08-16 18:17:38 -07005219 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
5220 for (int iw=wakeStats.size()-1; iw>=0; iw--) {
5221 Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005222 if (wl.reset()) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005223 wakeStats.removeAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005224 } else {
5225 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005226 }
5227 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005228 mWakelockStats.cleanup();
5229 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap();
5230 for (int is=syncStats.size()-1; is>=0; is--) {
5231 StopwatchTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005232 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005233 syncStats.removeAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005234 timer.detach();
5235 } else {
5236 active = true;
5237 }
5238 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005239 mSyncStats.cleanup();
5240 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
5241 for (int ij=jobStats.size()-1; ij>=0; ij--) {
5242 StopwatchTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005243 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005244 jobStats.removeAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005245 timer.detach();
5246 } else {
5247 active = true;
5248 }
5249 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005250 mJobStats.cleanup();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005251 for (int ise=mSensorStats.size()-1; ise>=0; ise--) {
5252 Sensor s = mSensorStats.valueAt(ise);
5253 if (s.reset()) {
5254 mSensorStats.removeAt(ise);
5255 } else {
5256 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005257 }
5258 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005259 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
5260 Proc proc = mProcessStats.valueAt(ip);
Dianne Hackborna8d10942015-11-19 17:55:19 -08005261 proc.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005262 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08005263 mProcessStats.clear();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005264 if (mPids.size() > 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005265 for (int i=mPids.size()-1; i>=0; i--) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005266 Pid pid = mPids.valueAt(i);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005267 if (pid.mWakeNesting > 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005268 active = true;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005269 } else {
5270 mPids.removeAt(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005271 }
5272 }
5273 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005274 if (mPackageStats.size() > 0) {
5275 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
5276 while (it.hasNext()) {
5277 Map.Entry<String, Pkg> pkgEntry = it.next();
5278 Pkg p = pkgEntry.getValue();
5279 p.detach();
5280 if (p.mServiceStats.size() > 0) {
5281 Iterator<Map.Entry<String, Pkg.Serv>> it2
5282 = p.mServiceStats.entrySet().iterator();
5283 while (it2.hasNext()) {
5284 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
5285 servEntry.getValue().detach();
5286 }
5287 }
5288 }
5289 mPackageStats.clear();
5290 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005291
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005292 mLastStepUserTime = mLastStepSystemTime = 0;
5293 mCurStepUserTime = mCurStepSystemTime = 0;
5294
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005295 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005296 if (mWifiRunningTimer != null) {
5297 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005298 }
5299 if (mFullWifiLockTimer != null) {
5300 mFullWifiLockTimer.detach();
5301 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005302 if (mWifiScanTimer != null) {
5303 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005304 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005305 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5306 if (mWifiBatchedScanTimer[i] != null) {
5307 mWifiBatchedScanTimer[i].detach();
5308 }
5309 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005310 if (mWifiMulticastTimer != null) {
5311 mWifiMulticastTimer.detach();
5312 }
5313 if (mAudioTurnedOnTimer != null) {
5314 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005315 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005316 }
5317 if (mVideoTurnedOnTimer != null) {
5318 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005319 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005320 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07005321 if (mFlashlightTurnedOnTimer != null) {
5322 mFlashlightTurnedOnTimer.detach();
5323 mFlashlightTurnedOnTimer = null;
5324 }
5325 if (mCameraTurnedOnTimer != null) {
5326 mCameraTurnedOnTimer.detach();
5327 mCameraTurnedOnTimer = null;
5328 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005329 if (mForegroundActivityTimer != null) {
5330 mForegroundActivityTimer.detach();
5331 mForegroundActivityTimer = null;
5332 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005333 if (mUserActivityCounters != null) {
5334 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5335 mUserActivityCounters[i].detach();
5336 }
5337 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005338 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005339 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005340 mNetworkByteActivityCounters[i].detach();
5341 mNetworkPacketActivityCounters[i].detach();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005342 }
5343 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005344
5345 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5346 if (mWifiControllerTime[i] != null) {
5347 mWifiControllerTime[i].detach();
5348 }
5349
5350 if (mBluetoothControllerTime[i] != null) {
5351 mBluetoothControllerTime[i].detach();
5352 }
5353 }
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005354 mPids.clear();
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005355
5356 mUserCpuTime.detach();
5357 mSystemCpuTime.detach();
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07005358 mCpuPower.detach();
Adam Lesinski6832f392015-09-05 18:05:40 -07005359
5360 if (mCpuClusterSpeed != null) {
5361 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) {
5362 if (cpuSpeeds != null) {
5363 for (LongSamplingCounter c : cpuSpeeds) {
5364 if (c != null) {
5365 c.detach();
5366 }
5367 }
5368 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005369 }
5370 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005371 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005372
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005373 return !active;
5374 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005375
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005376 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005377 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
5378 int NW = wakeStats.size();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005379 out.writeInt(NW);
5380 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005381 out.writeString(wakeStats.keyAt(iw));
5382 Uid.Wakelock wakelock = wakeStats.valueAt(iw);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005383 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005384 }
5385
Dianne Hackbornd953c532014-08-16 18:17:38 -07005386 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap();
5387 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005388 out.writeInt(NS);
5389 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005390 out.writeString(syncStats.keyAt(is));
5391 StopwatchTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005392 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
5393 }
5394
Dianne Hackbornd953c532014-08-16 18:17:38 -07005395 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
5396 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005397 out.writeInt(NJ);
5398 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005399 out.writeString(jobStats.keyAt(ij));
5400 StopwatchTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005401 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
5402 }
5403
Dianne Hackborn61659e52014-07-09 16:13:01 -07005404 int NSE = mSensorStats.size();
5405 out.writeInt(NSE);
5406 for (int ise=0; ise<NSE; ise++) {
5407 out.writeInt(mSensorStats.keyAt(ise));
5408 Uid.Sensor sensor = mSensorStats.valueAt(ise);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005409 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 }
5411
Dianne Hackborn61659e52014-07-09 16:13:01 -07005412 int NP = mProcessStats.size();
5413 out.writeInt(NP);
5414 for (int ip=0; ip<NP; ip++) {
5415 out.writeString(mProcessStats.keyAt(ip));
5416 Uid.Proc proc = mProcessStats.valueAt(ip);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005417 proc.writeToParcelLocked(out);
5418 }
5419
5420 out.writeInt(mPackageStats.size());
5421 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
5422 out.writeString(pkgEntry.getKey());
5423 Uid.Pkg pkg = pkgEntry.getValue();
5424 pkg.writeToParcelLocked(out);
5425 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005426
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005427 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005428 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005429 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005430 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005431 out.writeInt(0);
5432 }
5433 if (mFullWifiLockTimer != null) {
5434 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005435 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005436 } else {
5437 out.writeInt(0);
5438 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005439 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005440 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005441 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005442 } else {
5443 out.writeInt(0);
5444 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005445 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5446 if (mWifiBatchedScanTimer[i] != null) {
5447 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005448 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005449 } else {
5450 out.writeInt(0);
5451 }
5452 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005453 if (mWifiMulticastTimer != null) {
5454 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005455 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005456 } else {
5457 out.writeInt(0);
5458 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005459
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005460 if (mAudioTurnedOnTimer != null) {
5461 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005462 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005463 } else {
5464 out.writeInt(0);
5465 }
5466 if (mVideoTurnedOnTimer != null) {
5467 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005468 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005469 } else {
5470 out.writeInt(0);
5471 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07005472 if (mFlashlightTurnedOnTimer != null) {
5473 out.writeInt(1);
5474 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
5475 } else {
5476 out.writeInt(0);
5477 }
5478 if (mCameraTurnedOnTimer != null) {
5479 out.writeInt(1);
5480 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
5481 } else {
5482 out.writeInt(0);
5483 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005484 if (mForegroundActivityTimer != null) {
5485 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005486 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005487 } else {
5488 out.writeInt(0);
5489 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005490 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5491 if (mProcessStateTimer[i] != null) {
5492 out.writeInt(1);
5493 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs);
5494 } else {
5495 out.writeInt(0);
5496 }
5497 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005498 if (mVibratorOnTimer != null) {
5499 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005500 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005501 } else {
5502 out.writeInt(0);
5503 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005504 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07005505 out.writeInt(1);
5506 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5507 mUserActivityCounters[i].writeToParcel(out);
5508 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005509 } else {
5510 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005511 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005512 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005513 out.writeInt(1);
5514 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005515 mNetworkByteActivityCounters[i].writeToParcel(out);
5516 mNetworkPacketActivityCounters[i].writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005517 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005518 mMobileRadioActiveTime.writeToParcel(out);
5519 mMobileRadioActiveCount.writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005520 } else {
5521 out.writeInt(0);
5522 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005523
5524 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5525 if (mWifiControllerTime[i] != null) {
5526 out.writeInt(1);
5527 mWifiControllerTime[i].writeToParcel(out);
5528 } else {
5529 out.writeInt(0);
5530 }
5531 }
5532
5533 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5534 if (mBluetoothControllerTime[i] != null) {
5535 out.writeInt(1);
5536 mBluetoothControllerTime[i].writeToParcel(out);
5537 } else {
5538 out.writeInt(0);
5539 }
5540 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005541
5542 mUserCpuTime.writeToParcel(out);
5543 mSystemCpuTime.writeToParcel(out);
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07005544 mCpuPower.writeToParcel(out);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005545
Adam Lesinski6832f392015-09-05 18:05:40 -07005546 if (mCpuClusterSpeed != null) {
5547 out.writeInt(1);
5548 out.writeInt(mCpuClusterSpeed.length);
5549 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) {
5550 if (cpuSpeeds != null) {
5551 out.writeInt(1);
5552 out.writeInt(cpuSpeeds.length);
5553 for (LongSamplingCounter c : cpuSpeeds) {
5554 if (c != null) {
5555 out.writeInt(1);
5556 c.writeToParcel(out);
5557 } else {
5558 out.writeInt(0);
5559 }
5560 }
5561 } else {
5562 out.writeInt(0);
5563 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005564 }
Adam Lesinski6832f392015-09-05 18:05:40 -07005565 } else {
5566 out.writeInt(0);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005568 }
5569
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005570 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005571 int numWakelocks = in.readInt();
5572 mWakelockStats.clear();
5573 for (int j = 0; j < numWakelocks; j++) {
5574 String wakelockName = in.readString();
5575 Uid.Wakelock wakelock = new Wakelock();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005576 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
Dianne Hackbornd953c532014-08-16 18:17:38 -07005577 mWakelockStats.add(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005578 }
5579
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005580 int numSyncs = in.readInt();
5581 mSyncStats.clear();
5582 for (int j = 0; j < numSyncs; j++) {
5583 String syncName = in.readString();
5584 if (in.readInt() != 0) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005585 mSyncStats.add(syncName,
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005586 new StopwatchTimer(Uid.this, SYNC, null, timeBase, in));
5587 }
5588 }
5589
5590 int numJobs = in.readInt();
5591 mJobStats.clear();
5592 for (int j = 0; j < numJobs; j++) {
5593 String jobName = in.readString();
5594 if (in.readInt() != 0) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005595 mJobStats.add(jobName, new StopwatchTimer(Uid.this, JOB, null, timeBase, in));
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005596 }
5597 }
5598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005599 int numSensors = in.readInt();
5600 mSensorStats.clear();
5601 for (int k = 0; k < numSensors; k++) {
5602 int sensorNumber = in.readInt();
5603 Uid.Sensor sensor = new Sensor(sensorNumber);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005604 sensor.readFromParcelLocked(mOnBatteryTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005605 mSensorStats.put(sensorNumber, sensor);
5606 }
5607
5608 int numProcs = in.readInt();
5609 mProcessStats.clear();
5610 for (int k = 0; k < numProcs; k++) {
5611 String processName = in.readString();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005612 Uid.Proc proc = new Proc(processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005613 proc.readFromParcelLocked(in);
5614 mProcessStats.put(processName, proc);
5615 }
5616
5617 int numPkgs = in.readInt();
5618 mPackageStats.clear();
5619 for (int l = 0; l < numPkgs; l++) {
5620 String packageName = in.readString();
5621 Uid.Pkg pkg = new Pkg();
5622 pkg.readFromParcelLocked(in);
5623 mPackageStats.put(packageName, pkg);
5624 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005625
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005626 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005627 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005628 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005629 mWifiRunningTimers, mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005630 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005631 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005632 }
5633 mFullWifiLockOut = false;
5634 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005635 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005636 mFullWifiLockTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005637 } else {
5638 mFullWifiLockTimer = null;
5639 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005640 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005641 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005642 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005643 mWifiScanTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005644 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005645 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005646 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005647 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
5648 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5649 if (in.readInt() != 0) {
5650 makeWifiBatchedScanBin(i, in);
5651 } else {
5652 mWifiBatchedScanTimer[i] = null;
5653 }
5654 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005655 mWifiMulticastEnabled = false;
5656 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005657 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005658 mWifiMulticastTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005659 } else {
5660 mWifiMulticastTimer = null;
5661 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005662 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005663 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07005664 mAudioTurnedOnTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005665 } else {
5666 mAudioTurnedOnTimer = null;
5667 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005668 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005669 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07005670 mVideoTurnedOnTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005671 } else {
5672 mVideoTurnedOnTimer = null;
5673 }
5674 if (in.readInt() != 0) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -07005675 mFlashlightTurnedOnTimer = new StopwatchTimer(Uid.this, FLASHLIGHT_TURNED_ON,
5676 mFlashlightTurnedOnTimers, mOnBatteryTimeBase, in);
5677 } else {
5678 mFlashlightTurnedOnTimer = null;
5679 }
5680 if (in.readInt() != 0) {
5681 mCameraTurnedOnTimer = new StopwatchTimer(Uid.this, CAMERA_TURNED_ON,
5682 mCameraTurnedOnTimers, mOnBatteryTimeBase, in);
5683 } else {
5684 mCameraTurnedOnTimer = null;
5685 }
5686 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005687 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005688 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005689 } else {
5690 mForegroundActivityTimer = null;
5691 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08005692 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
Dianne Hackborn61659e52014-07-09 16:13:01 -07005693 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5694 if (in.readInt() != 0) {
5695 makeProcessState(i, in);
5696 } else {
5697 mProcessStateTimer[i] = null;
5698 }
5699 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005700 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005701 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005702 } else {
5703 mVibratorOnTimer = null;
5704 }
5705 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07005706 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
5707 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005708 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005709 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005710 } else {
5711 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07005712 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005713 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005714 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
5715 mNetworkPacketActivityCounters
5716 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005717 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005718 mNetworkByteActivityCounters[i]
5719 = new LongSamplingCounter(mOnBatteryTimeBase, in);
5720 mNetworkPacketActivityCounters[i]
5721 = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005722 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005723 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
5724 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005725 } else {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005726 mNetworkByteActivityCounters = null;
5727 mNetworkPacketActivityCounters = null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005728 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005729
5730 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5731 if (in.readInt() != 0) {
5732 mWifiControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
5733 } else {
5734 mWifiControllerTime[i] = null;
5735 }
5736 }
5737
5738 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5739 if (in.readInt() != 0) {
5740 mBluetoothControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
5741 } else {
5742 mBluetoothControllerTime[i] = null;
5743 }
5744 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005745
5746 mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
5747 mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07005748 mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase, in);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005749
Adam Lesinski6832f392015-09-05 18:05:40 -07005750 if (in.readInt() != 0) {
5751 int numCpuClusters = in.readInt();
5752 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numCpuClusters) {
5753 throw new ParcelFormatException("Incompatible number of cpu clusters");
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005754 }
Adam Lesinski6832f392015-09-05 18:05:40 -07005755
5756 mCpuClusterSpeed = new LongSamplingCounter[numCpuClusters][];
5757 for (int cluster = 0; cluster < numCpuClusters; cluster++) {
5758 if (in.readInt() != 0) {
5759 int numSpeeds = in.readInt();
5760 if (mPowerProfile != null &&
5761 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) {
5762 throw new ParcelFormatException("Incompatible number of cpu speeds");
5763 }
5764
5765 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds];
5766 mCpuClusterSpeed[cluster] = cpuSpeeds;
5767 for (int speed = 0; speed < numSpeeds; speed++) {
5768 if (in.readInt() != 0) {
5769 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase, in);
5770 }
5771 }
Adam Lesinskia57a5402015-09-28 10:21:33 -07005772 } else {
5773 mCpuClusterSpeed[cluster] = null;
Adam Lesinski6832f392015-09-05 18:05:40 -07005774 }
5775 }
5776 } else {
5777 mCpuClusterSpeed = null;
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005778 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005779 }
5780
5781 /**
5782 * The statistics associated with a particular wake lock.
5783 */
5784 public final class Wakelock extends BatteryStats.Uid.Wakelock {
5785 /**
5786 * How long (in ms) this uid has been keeping the device partially awake.
5787 */
Evan Millarc64edde2009-04-18 12:26:32 -07005788 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005789
5790 /**
5791 * How long (in ms) this uid has been keeping the device fully awake.
5792 */
Evan Millarc64edde2009-04-18 12:26:32 -07005793 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005794
5795 /**
5796 * How long (in ms) this uid has had a window keeping the device awake.
5797 */
Evan Millarc64edde2009-04-18 12:26:32 -07005798 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005799
5800 /**
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005801 * How long (in ms) this uid has had a draw wake lock.
Adam Lesinski9425fe22015-06-19 12:02:13 -07005802 */
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005803 StopwatchTimer mTimerDraw;
Adam Lesinski9425fe22015-06-19 12:02:13 -07005804
5805 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005806 * Reads a possibly null Timer from a Parcel. The timer is associated with the
5807 * proper timer pool from the given BatteryStatsImpl object.
5808 *
5809 * @param in the Parcel to be read from.
5810 * return a new Timer, or null.
5811 */
Evan Millarc64edde2009-04-18 12:26:32 -07005812 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005813 TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005814 if (in.readInt() == 0) {
5815 return null;
5816 }
5817
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005818 return new StopwatchTimer(Uid.this, type, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005819 }
5820
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005821 boolean reset() {
5822 boolean wlactive = false;
5823 if (mTimerFull != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005824 wlactive |= !mTimerFull.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005825 }
5826 if (mTimerPartial != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005827 wlactive |= !mTimerPartial.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005828 }
5829 if (mTimerWindow != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005830 wlactive |= !mTimerWindow.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005831 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005832 if (mTimerDraw != null) {
5833 wlactive |= !mTimerDraw.reset(false);
Adam Lesinski9425fe22015-06-19 12:02:13 -07005834 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005835 if (!wlactive) {
5836 if (mTimerFull != null) {
5837 mTimerFull.detach();
5838 mTimerFull = null;
5839 }
5840 if (mTimerPartial != null) {
5841 mTimerPartial.detach();
5842 mTimerPartial = null;
5843 }
5844 if (mTimerWindow != null) {
5845 mTimerWindow.detach();
5846 mTimerWindow = null;
5847 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005848 if (mTimerDraw != null) {
5849 mTimerDraw.detach();
5850 mTimerDraw = null;
Adam Lesinski9425fe22015-06-19 12:02:13 -07005851 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005852 }
5853 return !wlactive;
5854 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005855
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005856 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005857 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005858 mPartialTimers, screenOffTimeBase, in);
Adam Lesinski9425fe22015-06-19 12:02:13 -07005859 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, mFullTimers, timeBase, in);
5860 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, mWindowTimers, timeBase, in);
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005861 mTimerDraw = readTimerFromParcel(WAKE_TYPE_DRAW, mDrawTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005862 }
5863
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005864 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
5865 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
5866 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
5867 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005868 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 }
5870
5871 @Override
5872 public Timer getWakeTime(int type) {
5873 switch (type) {
5874 case WAKE_TYPE_FULL: return mTimerFull;
5875 case WAKE_TYPE_PARTIAL: return mTimerPartial;
5876 case WAKE_TYPE_WINDOW: return mTimerWindow;
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005877 case WAKE_TYPE_DRAW: return mTimerDraw;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005878 default: throw new IllegalArgumentException("type = " + type);
5879 }
5880 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005881
5882 public StopwatchTimer getStopwatchTimer(int type) {
5883 StopwatchTimer t;
5884 switch (type) {
5885 case WAKE_TYPE_PARTIAL:
5886 t = mTimerPartial;
5887 if (t == null) {
5888 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
5889 mPartialTimers, mOnBatteryScreenOffTimeBase);
5890 mTimerPartial = t;
5891 }
5892 return t;
5893 case WAKE_TYPE_FULL:
5894 t = mTimerFull;
5895 if (t == null) {
5896 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
5897 mFullTimers, mOnBatteryTimeBase);
5898 mTimerFull = t;
5899 }
5900 return t;
5901 case WAKE_TYPE_WINDOW:
5902 t = mTimerWindow;
5903 if (t == null) {
5904 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
5905 mWindowTimers, mOnBatteryTimeBase);
5906 mTimerWindow = t;
5907 }
5908 return t;
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005909 case WAKE_TYPE_DRAW:
5910 t = mTimerDraw;
Adam Lesinski9425fe22015-06-19 12:02:13 -07005911 if (t == null) {
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005912 t = new StopwatchTimer(Uid.this, WAKE_TYPE_DRAW,
5913 mDrawTimers, mOnBatteryTimeBase);
5914 mTimerDraw = t;
Adam Lesinski9425fe22015-06-19 12:02:13 -07005915 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07005916 return t;
Dianne Hackbornd953c532014-08-16 18:17:38 -07005917 default:
5918 throw new IllegalArgumentException("type=" + type);
5919 }
5920 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005921 }
5922
5923 public final class Sensor extends BatteryStats.Uid.Sensor {
5924 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07005925 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005927 public Sensor(int handle) {
5928 mHandle = handle;
5929 }
5930
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005931 private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005932 if (in.readInt() == 0) {
5933 return null;
5934 }
5935
Evan Millarc64edde2009-04-18 12:26:32 -07005936 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005937 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07005938 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 mSensorTimers.put(mHandle, pool);
5940 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005941 return new StopwatchTimer(Uid.this, 0, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005942 }
5943
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005944 boolean reset() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005945 if (mTimer.reset(true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005946 mTimer = null;
5947 return true;
5948 }
5949 return false;
5950 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005951
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005952 void readFromParcelLocked(TimeBase timeBase, Parcel in) {
5953 mTimer = readTimerFromParcel(timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005954 }
5955
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005956 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
5957 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005958 }
5959
5960 @Override
5961 public Timer getSensorTime() {
5962 return mTimer;
5963 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005964
5965 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005966 public int getHandle() {
5967 return mHandle;
5968 }
5969 }
5970
5971 /**
5972 * The statistics associated with a particular process.
5973 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005974 public final class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 /**
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005976 * The name of this process.
5977 */
5978 final String mName;
5979
5980 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -08005981 * Remains true until removed from the stats.
5982 */
5983 boolean mActive = true;
5984
5985 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005986 * Total time (in ms) spent executing in user code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005987 */
5988 long mUserTime;
5989
5990 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005991 * Total time (in ms) spent executing in kernel code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005992 */
5993 long mSystemTime;
5994
5995 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005996 * Amount of time (in ms) the process was running in the foreground.
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005997 */
5998 long mForegroundTime;
5999
6000 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006001 * Number of times the process has been started.
6002 */
6003 int mStarts;
6004
6005 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006006 * Number of times the process has crashed.
6007 */
6008 int mNumCrashes;
6009
6010 /**
6011 * Number of times the process has had an ANR.
6012 */
6013 int mNumAnrs;
6014
6015 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006016 * The amount of user time loaded from a previous save.
6017 */
6018 long mLoadedUserTime;
6019
6020 /**
6021 * The amount of system time loaded from a previous save.
6022 */
6023 long mLoadedSystemTime;
6024
6025 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006026 * The amount of foreground time loaded from a previous save.
6027 */
6028 long mLoadedForegroundTime;
6029
6030 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006031 * The number of times the process has started from a previous save.
6032 */
6033 int mLoadedStarts;
6034
6035 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006036 * Number of times the process has crashed from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006037 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006038 int mLoadedNumCrashes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006039
6040 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006041 * Number of times the process has had an ANR from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006042 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006043 int mLoadedNumAnrs;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006044
6045 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006046 * The amount of user time when last unplugged.
6047 */
6048 long mUnpluggedUserTime;
6049
6050 /**
6051 * The amount of system time when last unplugged.
6052 */
6053 long mUnpluggedSystemTime;
6054
6055 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006056 * The amount of foreground time since unplugged.
6057 */
6058 long mUnpluggedForegroundTime;
6059
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006060 /**
6061 * The number of times the process has started before unplugged.
6062 */
6063 int mUnpluggedStarts;
6064
Dianne Hackborn61659e52014-07-09 16:13:01 -07006065 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006066 * Number of times the process has crashed before unplugged.
6067 */
6068 int mUnpluggedNumCrashes;
6069
6070 /**
6071 * Number of times the process has had an ANR before unplugged.
6072 */
6073 int mUnpluggedNumAnrs;
6074
Dianne Hackborn287952c2010-09-22 22:34:31 -07006075 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006076
Dianne Hackborncd0e3352014-08-07 17:08:09 -07006077 Proc(String name) {
6078 mName = name;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006079 mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006080 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006081
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006082 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006083 mUnpluggedUserTime = mUserTime;
6084 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006085 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006086 mUnpluggedStarts = mStarts;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006087 mUnpluggedNumCrashes = mNumCrashes;
6088 mUnpluggedNumAnrs = mNumAnrs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006089 }
6090
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006091 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006092 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006093
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006094 void detach() {
Dianne Hackborn099bc622014-01-22 13:39:16 -08006095 mActive = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006096 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006097 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006098
Dianne Hackborn287952c2010-09-22 22:34:31 -07006099 public int countExcessivePowers() {
6100 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006101 }
6102
Dianne Hackborn287952c2010-09-22 22:34:31 -07006103 public ExcessivePower getExcessivePower(int i) {
6104 if (mExcessivePower != null) {
6105 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006106 }
6107 return null;
6108 }
6109
6110 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07006111 if (mExcessivePower == null) {
6112 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006113 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07006114 ExcessivePower ew = new ExcessivePower();
6115 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006116 ew.overTime = overTime;
6117 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07006118 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006119 }
6120
Dianne Hackborn287952c2010-09-22 22:34:31 -07006121 public void addExcessiveCpu(long overTime, long usedTime) {
6122 if (mExcessivePower == null) {
6123 mExcessivePower = new ArrayList<ExcessivePower>();
6124 }
6125 ExcessivePower ew = new ExcessivePower();
6126 ew.type = ExcessivePower.TYPE_CPU;
6127 ew.overTime = overTime;
6128 ew.usedTime = usedTime;
6129 mExcessivePower.add(ew);
6130 }
6131
6132 void writeExcessivePowerToParcelLocked(Parcel out) {
6133 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006134 out.writeInt(0);
6135 return;
6136 }
6137
Dianne Hackborn287952c2010-09-22 22:34:31 -07006138 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006139 out.writeInt(N);
6140 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07006141 ExcessivePower ew = mExcessivePower.get(i);
6142 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006143 out.writeLong(ew.overTime);
6144 out.writeLong(ew.usedTime);
6145 }
6146 }
6147
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07006148 void readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006149 final int N = in.readInt();
6150 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07006151 mExcessivePower = null;
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07006152 return;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006153 }
6154
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08006155 if (N > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07006156 throw new ParcelFormatException(
6157 "File corrupt: too many excessive power entries " + N);
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08006158 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006159
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07006160 mExcessivePower = new ArrayList<>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006161 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07006162 ExcessivePower ew = new ExcessivePower();
6163 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006164 ew.overTime = in.readLong();
6165 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07006166 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006167 }
6168 }
6169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006170 void writeToParcelLocked(Parcel out) {
6171 out.writeLong(mUserTime);
6172 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006173 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006174 out.writeInt(mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006175 out.writeInt(mNumCrashes);
6176 out.writeInt(mNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 out.writeLong(mLoadedUserTime);
6178 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006179 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006180 out.writeInt(mLoadedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006181 out.writeInt(mLoadedNumCrashes);
6182 out.writeInt(mLoadedNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 out.writeLong(mUnpluggedUserTime);
6184 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006185 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006186 out.writeInt(mUnpluggedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006187 out.writeInt(mUnpluggedNumCrashes);
6188 out.writeInt(mUnpluggedNumAnrs);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006189 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006190 }
6191
6192 void readFromParcelLocked(Parcel in) {
6193 mUserTime = in.readLong();
6194 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006195 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006196 mStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006197 mNumCrashes = in.readInt();
6198 mNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006199 mLoadedUserTime = in.readLong();
6200 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006201 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006202 mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006203 mLoadedNumCrashes = in.readInt();
6204 mLoadedNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006205 mUnpluggedUserTime = in.readLong();
6206 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006207 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006208 mUnpluggedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006209 mUnpluggedNumCrashes = in.readInt();
6210 mUnpluggedNumAnrs = in.readInt();
Dianne Hackborn287952c2010-09-22 22:34:31 -07006211 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006212 }
6213
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006214 public void addCpuTimeLocked(int utime, int stime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006215 mUserTime += utime;
6216 mSystemTime += stime;
6217 }
6218
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006219 public void addForegroundTimeLocked(long ttime) {
6220 mForegroundTime += ttime;
6221 }
6222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006223 public void incStartsLocked() {
6224 mStarts++;
6225 }
6226
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006227 public void incNumCrashesLocked() {
6228 mNumCrashes++;
6229 }
6230
6231 public void incNumAnrsLocked() {
6232 mNumAnrs++;
6233 }
6234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006235 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08006236 public boolean isActive() {
6237 return mActive;
6238 }
6239
6240 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006241 public long getUserTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006242 long val = mUserTime;
6243 if (which == STATS_CURRENT) {
6244 val -= mLoadedUserTime;
6245 } else if (which == STATS_SINCE_UNPLUGGED) {
6246 val -= mUnpluggedUserTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006247 }
6248 return val;
6249 }
6250
6251 @Override
6252 public long getSystemTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006253 long val = mSystemTime;
6254 if (which == STATS_CURRENT) {
6255 val -= mLoadedSystemTime;
6256 } else if (which == STATS_SINCE_UNPLUGGED) {
6257 val -= mUnpluggedSystemTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006258 }
6259 return val;
6260 }
6261
6262 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006263 public long getForegroundTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006264 long val = mForegroundTime;
6265 if (which == STATS_CURRENT) {
6266 val -= mLoadedForegroundTime;
6267 } else if (which == STATS_SINCE_UNPLUGGED) {
6268 val -= mUnpluggedForegroundTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006269 }
6270 return val;
6271 }
6272
6273 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006274 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006275 int val = mStarts;
6276 if (which == STATS_CURRENT) {
6277 val -= mLoadedStarts;
6278 } else if (which == STATS_SINCE_UNPLUGGED) {
6279 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006280 }
6281 return val;
6282 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006283
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006284 @Override
6285 public int getNumCrashes(int which) {
6286 int val = mNumCrashes;
6287 if (which == STATS_CURRENT) {
6288 val -= mLoadedNumCrashes;
6289 } else if (which == STATS_SINCE_UNPLUGGED) {
6290 val -= mUnpluggedNumCrashes;
6291 }
6292 return val;
6293 }
6294
6295 @Override
6296 public int getNumAnrs(int which) {
6297 int val = mNumAnrs;
6298 if (which == STATS_CURRENT) {
6299 val -= mLoadedNumAnrs;
6300 } else if (which == STATS_SINCE_UNPLUGGED) {
6301 val -= mUnpluggedNumAnrs;
6302 }
6303 return val;
6304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006305 }
6306
6307 /**
6308 * The statistics associated with a particular package.
6309 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006310 public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006311 /**
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006312 * Number of times wakeup alarms have occurred for this app.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006313 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006314 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006315
6316 /**
6317 * The statics we have collected for this package's services.
6318 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006319 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006320
6321 Pkg() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006322 mOnBatteryScreenOffTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006323 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006324
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006325 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006326 }
6327
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006328 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006329 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006330
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006331 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006332 mOnBatteryScreenOffTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006333 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006335 void readFromParcelLocked(Parcel in) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006336 int numWA = in.readInt();
6337 mWakeupAlarms.clear();
6338 for (int i=0; i<numWA; i++) {
6339 String tag = in.readString();
6340 mWakeupAlarms.put(tag, new Counter(mOnBatteryTimeBase, in));
6341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006342
6343 int numServs = in.readInt();
6344 mServiceStats.clear();
6345 for (int m = 0; m < numServs; m++) {
6346 String serviceName = in.readString();
6347 Uid.Pkg.Serv serv = new Serv();
6348 mServiceStats.put(serviceName, serv);
6349
6350 serv.readFromParcelLocked(in);
6351 }
6352 }
6353
6354 void writeToParcelLocked(Parcel out) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006355 int numWA = mWakeupAlarms.size();
6356 out.writeInt(numWA);
6357 for (int i=0; i<numWA; i++) {
6358 out.writeString(mWakeupAlarms.keyAt(i));
6359 mWakeupAlarms.valueAt(i).writeToParcel(out);
6360 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006361
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006362 final int NS = mServiceStats.size();
6363 out.writeInt(NS);
6364 for (int i=0; i<NS; i++) {
6365 out.writeString(mServiceStats.keyAt(i));
6366 Uid.Pkg.Serv serv = mServiceStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006367 serv.writeToParcelLocked(out);
6368 }
6369 }
6370
6371 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006372 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() {
6373 return mWakeupAlarms;
6374 }
6375
6376 public void noteWakeupAlarmLocked(String tag) {
6377 Counter c = mWakeupAlarms.get(tag);
6378 if (c == null) {
6379 c = new Counter(mOnBatteryTimeBase);
6380 mWakeupAlarms.put(tag, c);
6381 }
6382 c.stepAtomic();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006383 }
6384
6385 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006386 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
6387 return mServiceStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006388 }
6389
6390 /**
6391 * The statistics associated with a particular service.
6392 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006393 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006394 /**
6395 * Total time (ms in battery uptime) the service has been left started.
6396 */
6397 long mStartTime;
6398
6399 /**
6400 * If service has been started and not yet stopped, this is
6401 * when it was started.
6402 */
6403 long mRunningSince;
6404
6405 /**
6406 * True if we are currently running.
6407 */
6408 boolean mRunning;
6409
6410 /**
6411 * Total number of times startService() has been called.
6412 */
6413 int mStarts;
6414
6415 /**
6416 * Total time (ms in battery uptime) the service has been left launched.
6417 */
6418 long mLaunchedTime;
6419
6420 /**
6421 * If service has been launched and not yet exited, this is
6422 * when it was launched (ms in battery uptime).
6423 */
6424 long mLaunchedSince;
6425
6426 /**
6427 * True if we are currently launched.
6428 */
6429 boolean mLaunched;
6430
6431 /**
6432 * Total number times the service has been launched.
6433 */
6434 int mLaunches;
6435
6436 /**
6437 * The amount of time spent started loaded from a previous save
6438 * (ms in battery uptime).
6439 */
6440 long mLoadedStartTime;
6441
6442 /**
6443 * The number of starts loaded from a previous save.
6444 */
6445 int mLoadedStarts;
6446
6447 /**
6448 * The number of launches loaded from a previous save.
6449 */
6450 int mLoadedLaunches;
6451
6452 /**
6453 * The amount of time spent started as of the last run (ms
6454 * in battery uptime).
6455 */
6456 long mLastStartTime;
6457
6458 /**
6459 * The number of starts as of the last run.
6460 */
6461 int mLastStarts;
6462
6463 /**
6464 * The number of launches as of the last run.
6465 */
6466 int mLastLaunches;
6467
6468 /**
6469 * The amount of time spent started when last unplugged (ms
6470 * in battery uptime).
6471 */
6472 long mUnpluggedStartTime;
6473
6474 /**
6475 * The number of starts when last unplugged.
6476 */
6477 int mUnpluggedStarts;
6478
6479 /**
6480 * The number of launches when last unplugged.
6481 */
6482 int mUnpluggedLaunches;
6483
6484 Serv() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006485 mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006486 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006487
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006488 public void onTimeStarted(long elapsedRealtime, long baseUptime,
6489 long baseRealtime) {
6490 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006491 mUnpluggedStarts = mStarts;
6492 mUnpluggedLaunches = mLaunches;
6493 }
6494
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006495 public void onTimeStopped(long elapsedRealtime, long baseUptime,
6496 long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006497 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006498
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006499 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006500 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006501 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006503 void readFromParcelLocked(Parcel in) {
6504 mStartTime = in.readLong();
6505 mRunningSince = in.readLong();
6506 mRunning = in.readInt() != 0;
6507 mStarts = in.readInt();
6508 mLaunchedTime = in.readLong();
6509 mLaunchedSince = in.readLong();
6510 mLaunched = in.readInt() != 0;
6511 mLaunches = in.readInt();
6512 mLoadedStartTime = in.readLong();
6513 mLoadedStarts = in.readInt();
6514 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006515 mLastStartTime = 0;
6516 mLastStarts = 0;
6517 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006518 mUnpluggedStartTime = in.readLong();
6519 mUnpluggedStarts = in.readInt();
6520 mUnpluggedLaunches = in.readInt();
6521 }
6522
6523 void writeToParcelLocked(Parcel out) {
6524 out.writeLong(mStartTime);
6525 out.writeLong(mRunningSince);
6526 out.writeInt(mRunning ? 1 : 0);
6527 out.writeInt(mStarts);
6528 out.writeLong(mLaunchedTime);
6529 out.writeLong(mLaunchedSince);
6530 out.writeInt(mLaunched ? 1 : 0);
6531 out.writeInt(mLaunches);
6532 out.writeLong(mLoadedStartTime);
6533 out.writeInt(mLoadedStarts);
6534 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006535 out.writeLong(mUnpluggedStartTime);
6536 out.writeInt(mUnpluggedStarts);
6537 out.writeInt(mUnpluggedLaunches);
6538 }
6539
6540 long getLaunchTimeToNowLocked(long batteryUptime) {
6541 if (!mLaunched) return mLaunchedTime;
6542 return mLaunchedTime + batteryUptime - mLaunchedSince;
6543 }
6544
6545 long getStartTimeToNowLocked(long batteryUptime) {
6546 if (!mRunning) return mStartTime;
6547 return mStartTime + batteryUptime - mRunningSince;
6548 }
6549
6550 public void startLaunchedLocked() {
6551 if (!mLaunched) {
6552 mLaunches++;
6553 mLaunchedSince = getBatteryUptimeLocked();
6554 mLaunched = true;
6555 }
6556 }
6557
6558 public void stopLaunchedLocked() {
6559 if (mLaunched) {
6560 long time = getBatteryUptimeLocked() - mLaunchedSince;
6561 if (time > 0) {
6562 mLaunchedTime += time;
6563 } else {
6564 mLaunches--;
6565 }
6566 mLaunched = false;
6567 }
6568 }
6569
6570 public void startRunningLocked() {
6571 if (!mRunning) {
6572 mStarts++;
6573 mRunningSince = getBatteryUptimeLocked();
6574 mRunning = true;
6575 }
6576 }
6577
6578 public void stopRunningLocked() {
6579 if (mRunning) {
6580 long time = getBatteryUptimeLocked() - mRunningSince;
6581 if (time > 0) {
6582 mStartTime += time;
6583 } else {
6584 mStarts--;
6585 }
6586 mRunning = false;
6587 }
6588 }
6589
6590 public BatteryStatsImpl getBatteryStats() {
6591 return BatteryStatsImpl.this;
6592 }
6593
6594 @Override
6595 public int getLaunches(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006596 int val = mLaunches;
6597 if (which == STATS_CURRENT) {
6598 val -= mLoadedLaunches;
6599 } else if (which == STATS_SINCE_UNPLUGGED) {
6600 val -= mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006601 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006602 return val;
6603 }
6604
6605 @Override
6606 public long getStartTime(long now, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006607 long val = getStartTimeToNowLocked(now);
6608 if (which == STATS_CURRENT) {
6609 val -= mLoadedStartTime;
6610 } else if (which == STATS_SINCE_UNPLUGGED) {
6611 val -= mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006612 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006613 return val;
6614 }
6615
6616 @Override
6617 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006618 int val = mStarts;
6619 if (which == STATS_CURRENT) {
6620 val -= mLoadedStarts;
6621 } else if (which == STATS_SINCE_UNPLUGGED) {
6622 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006623 }
6624
6625 return val;
6626 }
6627 }
6628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006629 final Serv newServiceStatsLocked() {
6630 return new Serv();
6631 }
6632 }
6633
6634 /**
6635 * Retrieve the statistics object for a particular process, creating
6636 * if needed.
6637 */
6638 public Proc getProcessStatsLocked(String name) {
6639 Proc ps = mProcessStats.get(name);
6640 if (ps == null) {
Dianne Hackborncd0e3352014-08-07 17:08:09 -07006641 ps = new Proc(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006642 mProcessStats.put(name, ps);
6643 }
6644
6645 return ps;
6646 }
6647
Dianne Hackborna8d10942015-11-19 17:55:19 -08006648 public void updateUidProcessStateLocked(int procState) {
6649 int uidRunningState;
6650 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
6651 uidRunningState = ActivityManager.PROCESS_STATE_NONEXISTENT;
6652 } else if (procState == ActivityManager.PROCESS_STATE_TOP) {
6653 uidRunningState = PROCESS_STATE_TOP;
6654 } else if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
6655 // Persistent and other foreground states go here.
6656 uidRunningState = PROCESS_STATE_FOREGROUND_SERVICE;
6657 } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
6658 uidRunningState = PROCESS_STATE_TOP_SLEEPING;
6659 } else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
6660 // Persistent and other foreground states go here.
6661 uidRunningState = PROCESS_STATE_FOREGROUND;
6662 } else if (procState <= ActivityManager.PROCESS_STATE_RECEIVER) {
6663 uidRunningState = PROCESS_STATE_BACKGROUND;
Dianne Hackborn61659e52014-07-09 16:13:01 -07006664 } else {
Dianne Hackborna8d10942015-11-19 17:55:19 -08006665 uidRunningState = PROCESS_STATE_CACHED;
Dianne Hackborn61659e52014-07-09 16:13:01 -07006666 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07006667
Dianne Hackborna8d10942015-11-19 17:55:19 -08006668 if (mProcessState == uidRunningState) return;
6669
6670 final long elapsedRealtime = SystemClock.elapsedRealtime();
6671
6672 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
6673 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtime);
6674 }
6675 mProcessState = uidRunningState;
6676 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
6677 if (mProcessStateTimer[uidRunningState] == null) {
6678 makeProcessState(uidRunningState, null);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006679 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08006680 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtime);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006681 }
6682 }
6683
Dianne Hackbornb5e31652010-09-07 12:13:55 -07006684 public SparseArray<? extends Pid> getPidStats() {
6685 return mPids;
6686 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006687
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006688 public Pid getPidStatsLocked(int pid) {
6689 Pid p = mPids.get(pid);
6690 if (p == null) {
6691 p = new Pid();
6692 mPids.put(pid, p);
6693 }
6694 return p;
6695 }
6696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006697 /**
6698 * Retrieve the statistics object for a particular service, creating
6699 * if needed.
6700 */
6701 public Pkg getPackageStatsLocked(String name) {
6702 Pkg ps = mPackageStats.get(name);
6703 if (ps == null) {
6704 ps = new Pkg();
6705 mPackageStats.put(name, ps);
6706 }
6707
6708 return ps;
6709 }
6710
6711 /**
6712 * Retrieve the statistics object for a particular service, creating
6713 * if needed.
6714 */
6715 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
6716 Pkg ps = getPackageStatsLocked(pkg);
6717 Pkg.Serv ss = ps.mServiceStats.get(serv);
6718 if (ss == null) {
6719 ss = ps.newServiceStatsLocked();
6720 ps.mServiceStats.put(serv, ss);
6721 }
6722
6723 return ss;
6724 }
6725
Dianne Hackbornd953c532014-08-16 18:17:38 -07006726 public void readSyncSummaryFromParcelLocked(String name, Parcel in) {
6727 StopwatchTimer timer = mSyncStats.instantiateObject();
6728 timer.readSummaryFromParcelLocked(in);
6729 mSyncStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006730 }
6731
Dianne Hackbornd953c532014-08-16 18:17:38 -07006732 public void readJobSummaryFromParcelLocked(String name, Parcel in) {
6733 StopwatchTimer timer = mJobStats.instantiateObject();
6734 timer.readSummaryFromParcelLocked(in);
6735 mJobStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006736 }
6737
Dianne Hackbornd953c532014-08-16 18:17:38 -07006738 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) {
6739 Wakelock wl = new Wakelock();
6740 mWakelockStats.add(wlName, wl);
6741 if (in.readInt() != 0) {
6742 wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006743 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006744 if (in.readInt() != 0) {
6745 wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
6746 }
6747 if (in.readInt() != 0) {
6748 wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006749 }
Adam Lesinski9425fe22015-06-19 12:02:13 -07006750 if (in.readInt() != 0) {
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07006751 wl.getStopwatchTimer(WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
Adam Lesinski9425fe22015-06-19 12:02:13 -07006752 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006753 }
6754
Evan Millarc64edde2009-04-18 12:26:32 -07006755 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006756 Sensor se = mSensorStats.get(sensor);
6757 if (se == null) {
6758 if (!create) {
6759 return null;
6760 }
6761 se = new Sensor(sensor);
6762 mSensorStats.put(sensor, se);
6763 }
Evan Millarc64edde2009-04-18 12:26:32 -07006764 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006765 if (t != null) {
6766 return t;
6767 }
Evan Millarc64edde2009-04-18 12:26:32 -07006768 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07006770 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006771 mSensorTimers.put(sensor, timers);
6772 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006773 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006774 se.mTimer = t;
6775 return t;
6776 }
6777
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006778 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006779 StopwatchTimer t = mSyncStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006780 if (t != null) {
6781 t.startRunningLocked(elapsedRealtimeMs);
6782 }
6783 }
6784
6785 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006786 StopwatchTimer t = mSyncStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006787 if (t != null) {
6788 t.stopRunningLocked(elapsedRealtimeMs);
6789 }
6790 }
6791
6792 public void noteStartJobLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07006793 StopwatchTimer t = mJobStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006794 if (t != null) {
6795 t.startRunningLocked(elapsedRealtimeMs);
6796 }
6797 }
6798
6799 public void noteStopJobLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006800 StopwatchTimer t = mJobStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006801 if (t != null) {
6802 t.stopRunningLocked(elapsedRealtimeMs);
6803 }
6804 }
6805
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006806 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006807 Wakelock wl = mWakelockStats.startObject(name);
6808 if (wl != null) {
6809 wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006810 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07006811 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006812 Pid p = getPidStatsLocked(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006813 if (p.mWakeNesting++ == 0) {
6814 p.mWakeStartMs = elapsedRealtimeMs;
Dianne Hackbornb8071d792010-09-09 16:45:15 -07006815 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006817 }
6818
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006819 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006820 Wakelock wl = mWakelockStats.stopObject(name);
6821 if (wl != null) {
6822 wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006823 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07006824 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006825 Pid p = mPids.get(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006826 if (p != null && p.mWakeNesting > 0) {
6827 if (p.mWakeNesting-- == 1) {
6828 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
6829 p.mWakeStartMs = 0;
6830 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006831 }
6832 }
6833 }
6834
6835 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
6836 Proc p = getProcessStatsLocked(proc);
6837 if (p != null) {
6838 p.addExcessiveWake(overTime, usedTime);
6839 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006840 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006841
Dianne Hackborn287952c2010-09-22 22:34:31 -07006842 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
6843 Proc p = getProcessStatsLocked(proc);
6844 if (p != null) {
6845 p.addExcessiveCpu(overTime, usedTime);
6846 }
6847 }
6848
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006849 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006850 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006851 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006852 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006853 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006854 }
6855
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006856 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006857 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07006858 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006859 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006860 t.stopRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006861 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006862 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006863
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006864 public void noteStartGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006865 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006866 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006867 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006868 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006869 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006870
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006871 public void noteStopGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006872 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006873 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006874 t.stopRunningLocked(elapsedRealtimeMs);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07006875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006876 }
6877
6878 public BatteryStatsImpl getBatteryStats() {
6879 return BatteryStatsImpl.this;
6880 }
6881 }
6882
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006883 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07006884 if (systemDir != null) {
6885 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"),
6886 new File(systemDir, "batterystats.bin.tmp"));
6887 } else {
6888 mFile = null;
6889 }
6890 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006891 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006892 mExternalSync = externalSync;
Jeff Brown6f357d32014-01-15 20:40:55 -08006893 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006894 mStartCount++;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006895 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006896 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006897 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006898 }
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07006899 mInteractiveTimer = new StopwatchTimer(null, -10, null, mOnBatteryTimeBase);
6900 mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07006901 mDeviceIdleModeLightTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase);
6902 mDeviceIdleModeFullTimer = new StopwatchTimer(null, -14, null, mOnBatteryTimeBase);
6903 mDeviceLightIdlingTimer = new StopwatchTimer(null, -15, null, mOnBatteryTimeBase);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006904 mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006905 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase);
Wink Saville52840902011-02-18 12:40:47 -08006906 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006907 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null,
6908 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006909 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006910 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006911 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006912 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null,
6913 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006914 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006915 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006916 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6917 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006918 }
Adam Lesinski33dac552015-03-09 15:24:48 -07006919 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
6920 mBluetoothActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6921 mWifiActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6922 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006923 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase);
6924 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006925 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006926 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
6927 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006928 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase);
6929 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006930 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006931 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006932 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07006933 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
6934 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i, null, mOnBatteryTimeBase);
6935 }
6936 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
6937 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i, null,
6938 mOnBatteryTimeBase);
6939 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006940 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
6941 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07006942 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006943 mCameraOnTimer = new StopwatchTimer(null, -13, null, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006944 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006945 long uptime = SystemClock.uptimeMillis() * 1000;
6946 long realtime = SystemClock.elapsedRealtime() * 1000;
6947 initTimes(uptime, realtime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07006948 mStartPlatformVersion = mEndPlatformVersion = Build.ID;
Evan Millar633a1742009-04-02 16:36:33 -07006949 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006950 mDischargeUnplugLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006951 mDischargePlugLevel = -1;
Evan Millar633a1742009-04-02 16:36:33 -07006952 mDischargeCurrentLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006953 mCurrentBatteryLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006954 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006955 clearHistoryLocked();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006956 updateDailyDeadlineLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 }
6958
6959 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006960 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07006961 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006962 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07006963 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006964 mExternalSync = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006965 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006966 readFromParcel(p);
6967 }
6968
Adam Lesinskie08af192015-03-25 16:42:59 -07006969 public void setPowerProfile(PowerProfile profile) {
6970 synchronized (this) {
6971 mPowerProfile = profile;
Adam Lesinski6832f392015-09-05 18:05:40 -07006972
6973 // We need to initialize the KernelCpuSpeedReaders to read from
6974 // the first cpu of each core. Once we have the PowerProfile, we have access to this
6975 // information.
6976 final int numClusters = mPowerProfile.getNumCpuClusters();
6977 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
6978 int firstCpuOfCluster = 0;
6979 for (int i = 0; i < numClusters; i++) {
6980 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i);
6981 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
6982 numSpeedSteps);
6983 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i);
6984 }
Adam Lesinskie08af192015-03-25 16:42:59 -07006985 }
6986 }
6987
Dianne Hackborn0d903a82010-09-07 23:51:03 -07006988 public void setCallback(BatteryCallback cb) {
6989 mCallback = cb;
6990 }
6991
Amith Yamasanif37447b2009-10-08 18:28:01 -07006992 public void setRadioScanningTimeout(long timeout) {
6993 if (mPhoneSignalScanningTimer != null) {
6994 mPhoneSignalScanningTimer.setTimeout(timeout);
6995 }
6996 }
6997
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006998 public void updateDailyDeadlineLocked() {
6999 // Get the current time.
7000 long currentTime = mDailyStartTime = System.currentTimeMillis();
7001 Calendar calDeadline = Calendar.getInstance();
7002 calDeadline.setTimeInMillis(currentTime);
7003
7004 // Move time up to the next day, ranging from 1am to 3pm.
7005 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1);
7006 calDeadline.set(Calendar.MILLISECOND, 0);
7007 calDeadline.set(Calendar.SECOND, 0);
7008 calDeadline.set(Calendar.MINUTE, 0);
7009 calDeadline.set(Calendar.HOUR_OF_DAY, 1);
7010 mNextMinDailyDeadline = calDeadline.getTimeInMillis();
7011 calDeadline.set(Calendar.HOUR_OF_DAY, 3);
7012 mNextMaxDailyDeadline = calDeadline.getTimeInMillis();
7013 }
7014
7015 public void recordDailyStatsIfNeededLocked(boolean settled) {
7016 long currentTime = System.currentTimeMillis();
7017 if (currentTime >= mNextMaxDailyDeadline) {
7018 recordDailyStatsLocked();
7019 } else if (settled && currentTime >= mNextMinDailyDeadline) {
7020 recordDailyStatsLocked();
7021 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) {
7022 recordDailyStatsLocked();
7023 }
7024 }
7025
7026 public void recordDailyStatsLocked() {
7027 DailyItem item = new DailyItem();
7028 item.mStartTime = mDailyStartTime;
7029 item.mEndTime = System.currentTimeMillis();
7030 boolean hasData = false;
7031 if (mDailyDischargeStepTracker.mNumStepDurations > 0) {
7032 hasData = true;
7033 item.mDischargeSteps = new LevelStepTracker(
7034 mDailyDischargeStepTracker.mNumStepDurations,
7035 mDailyDischargeStepTracker.mStepDurations);
7036 }
7037 if (mDailyChargeStepTracker.mNumStepDurations > 0) {
7038 hasData = true;
7039 item.mChargeSteps = new LevelStepTracker(
7040 mDailyChargeStepTracker.mNumStepDurations,
7041 mDailyChargeStepTracker.mStepDurations);
7042 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007043 if (mDailyPackageChanges != null) {
7044 hasData = true;
7045 item.mPackageChanges = mDailyPackageChanges;
7046 mDailyPackageChanges = null;
7047 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007048 mDailyDischargeStepTracker.init();
7049 mDailyChargeStepTracker.init();
7050 updateDailyDeadlineLocked();
7051
7052 if (hasData) {
7053 mDailyItems.add(item);
7054 while (mDailyItems.size() > MAX_DAILY_ITEMS) {
7055 mDailyItems.remove(0);
7056 }
7057 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
7058 try {
7059 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01007060 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007061 writeDailyItemsLocked(out);
7062 BackgroundThread.getHandler().post(new Runnable() {
7063 @Override
7064 public void run() {
7065 synchronized (mCheckinFile) {
7066 FileOutputStream stream = null;
7067 try {
7068 stream = mDailyFile.startWrite();
7069 memStream.writeTo(stream);
7070 stream.flush();
7071 FileUtils.sync(stream);
7072 stream.close();
7073 mDailyFile.finishWrite(stream);
7074 } catch (IOException e) {
7075 Slog.w("BatteryStats",
7076 "Error writing battery daily items", e);
7077 mDailyFile.failWrite(stream);
7078 }
7079 }
7080 }
7081 });
7082 } catch (IOException e) {
7083 }
7084 }
7085 }
7086
7087 private void writeDailyItemsLocked(XmlSerializer out) throws IOException {
7088 StringBuilder sb = new StringBuilder(64);
7089 out.startDocument(null, true);
7090 out.startTag(null, "daily-items");
7091 for (int i=0; i<mDailyItems.size(); i++) {
7092 final DailyItem dit = mDailyItems.get(i);
7093 out.startTag(null, "item");
7094 out.attribute(null, "start", Long.toString(dit.mStartTime));
7095 out.attribute(null, "end", Long.toString(dit.mEndTime));
7096 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb);
7097 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007098 if (dit.mPackageChanges != null) {
7099 for (int j=0; j<dit.mPackageChanges.size(); j++) {
7100 PackageChange pc = dit.mPackageChanges.get(j);
7101 if (pc.mUpdate) {
7102 out.startTag(null, "upd");
7103 out.attribute(null, "pkg", pc.mPackageName);
7104 out.attribute(null, "ver", Integer.toString(pc.mVersionCode));
7105 out.endTag(null, "upd");
7106 } else {
7107 out.startTag(null, "rem");
7108 out.attribute(null, "pkg", pc.mPackageName);
7109 out.endTag(null, "rem");
7110 }
7111 }
7112 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007113 out.endTag(null, "item");
7114 }
7115 out.endTag(null, "daily-items");
7116 out.endDocument();
7117 }
7118
7119 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps,
7120 StringBuilder tmpBuilder) throws IOException {
7121 if (steps != null) {
7122 out.startTag(null, tag);
7123 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations));
7124 for (int i=0; i<steps.mNumStepDurations; i++) {
7125 out.startTag(null, "s");
7126 tmpBuilder.setLength(0);
7127 steps.encodeEntryAt(i, tmpBuilder);
7128 out.attribute(null, "v", tmpBuilder.toString());
7129 out.endTag(null, "s");
7130 }
7131 out.endTag(null, tag);
7132 }
7133 }
7134
7135 public void readDailyStatsLocked() {
7136 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile());
7137 mDailyItems.clear();
7138 FileInputStream stream;
7139 try {
7140 stream = mDailyFile.openRead();
7141 } catch (FileNotFoundException e) {
7142 return;
7143 }
7144 try {
7145 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01007146 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007147 readDailyItemsLocked(parser);
7148 } catch (XmlPullParserException e) {
7149 } finally {
7150 try {
7151 stream.close();
7152 } catch (IOException e) {
7153 }
7154 }
7155 }
7156
7157 private void readDailyItemsLocked(XmlPullParser parser) {
7158 try {
7159 int type;
7160 while ((type = parser.next()) != XmlPullParser.START_TAG
7161 && type != XmlPullParser.END_DOCUMENT) {
7162 ;
7163 }
7164
7165 if (type != XmlPullParser.START_TAG) {
7166 throw new IllegalStateException("no start tag found");
7167 }
7168
7169 int outerDepth = parser.getDepth();
7170 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
7171 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
7172 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
7173 continue;
7174 }
7175
7176 String tagName = parser.getName();
7177 if (tagName.equals("item")) {
7178 readDailyItemTagLocked(parser);
7179 } else {
7180 Slog.w(TAG, "Unknown element under <daily-items>: "
7181 + parser.getName());
7182 XmlUtils.skipCurrentTag(parser);
7183 }
7184 }
7185
7186 } catch (IllegalStateException e) {
7187 Slog.w(TAG, "Failed parsing daily " + e);
7188 } catch (NullPointerException e) {
7189 Slog.w(TAG, "Failed parsing daily " + e);
7190 } catch (NumberFormatException e) {
7191 Slog.w(TAG, "Failed parsing daily " + e);
7192 } catch (XmlPullParserException e) {
7193 Slog.w(TAG, "Failed parsing daily " + e);
7194 } catch (IOException e) {
7195 Slog.w(TAG, "Failed parsing daily " + e);
7196 } catch (IndexOutOfBoundsException e) {
7197 Slog.w(TAG, "Failed parsing daily " + e);
7198 }
7199 }
7200
7201 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException,
7202 XmlPullParserException, IOException {
7203 DailyItem dit = new DailyItem();
7204 String attr = parser.getAttributeValue(null, "start");
7205 if (attr != null) {
7206 dit.mStartTime = Long.parseLong(attr);
7207 }
7208 attr = parser.getAttributeValue(null, "end");
7209 if (attr != null) {
7210 dit.mEndTime = Long.parseLong(attr);
7211 }
7212 int outerDepth = parser.getDepth();
7213 int type;
7214 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
7215 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
7216 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
7217 continue;
7218 }
7219
7220 String tagName = parser.getName();
7221 if (tagName.equals("dis")) {
7222 readDailyItemTagDetailsLocked(parser, dit, false, "dis");
7223 } else if (tagName.equals("chg")) {
7224 readDailyItemTagDetailsLocked(parser, dit, true, "chg");
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007225 } else if (tagName.equals("upd")) {
7226 if (dit.mPackageChanges == null) {
7227 dit.mPackageChanges = new ArrayList<>();
7228 }
7229 PackageChange pc = new PackageChange();
7230 pc.mUpdate = true;
7231 pc.mPackageName = parser.getAttributeValue(null, "pkg");
7232 String verStr = parser.getAttributeValue(null, "ver");
7233 pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0;
7234 dit.mPackageChanges.add(pc);
7235 XmlUtils.skipCurrentTag(parser);
7236 } else if (tagName.equals("rem")) {
7237 if (dit.mPackageChanges == null) {
7238 dit.mPackageChanges = new ArrayList<>();
7239 }
7240 PackageChange pc = new PackageChange();
7241 pc.mUpdate = false;
7242 pc.mPackageName = parser.getAttributeValue(null, "pkg");
7243 dit.mPackageChanges.add(pc);
7244 XmlUtils.skipCurrentTag(parser);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007245 } else {
7246 Slog.w(TAG, "Unknown element under <item>: "
7247 + parser.getName());
7248 XmlUtils.skipCurrentTag(parser);
7249 }
7250 }
7251 mDailyItems.add(dit);
7252 }
7253
7254 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge,
7255 String tag)
7256 throws NumberFormatException, XmlPullParserException, IOException {
7257 final String numAttr = parser.getAttributeValue(null, "n");
7258 if (numAttr == null) {
7259 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription());
7260 XmlUtils.skipCurrentTag(parser);
7261 return;
7262 }
7263 final int num = Integer.parseInt(numAttr);
7264 LevelStepTracker steps = new LevelStepTracker(num);
7265 if (isCharge) {
7266 dit.mChargeSteps = steps;
7267 } else {
7268 dit.mDischargeSteps = steps;
7269 }
7270 int i = 0;
7271 int outerDepth = parser.getDepth();
7272 int type;
7273 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
7274 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
7275 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
7276 continue;
7277 }
7278
7279 String tagName = parser.getName();
7280 if ("s".equals(tagName)) {
7281 if (i < num) {
7282 String valueAttr = parser.getAttributeValue(null, "v");
7283 if (valueAttr != null) {
7284 steps.decodeEntryAt(i, valueAttr);
7285 i++;
7286 }
7287 }
7288 } else {
7289 Slog.w(TAG, "Unknown element under <" + tag + ">: "
7290 + parser.getName());
7291 XmlUtils.skipCurrentTag(parser);
7292 }
7293 }
7294 steps.mNumStepDurations = i;
7295 }
7296
7297 @Override
7298 public DailyItem getDailyItemLocked(int daysAgo) {
7299 int index = mDailyItems.size()-1-daysAgo;
7300 return index >= 0 ? mDailyItems.get(index) : null;
7301 }
7302
7303 @Override
7304 public long getCurrentDailyStartTime() {
7305 return mDailyStartTime;
7306 }
7307
7308 @Override
7309 public long getNextMinDailyDeadline() {
7310 return mNextMinDailyDeadline;
7311 }
7312
7313 @Override
7314 public long getNextMaxDailyDeadline() {
7315 return mNextMaxDailyDeadline;
7316 }
7317
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007318 @Override
7319 public boolean startIteratingOldHistoryLocked() {
7320 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
7321 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007322 if ((mHistoryIterator = mHistory) == null) {
7323 return false;
7324 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007325 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007326 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007327 mReadOverflow = false;
7328 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007329 return true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007330 }
7331
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007332 @Override
7333 public boolean getNextOldHistoryLocked(HistoryItem out) {
7334 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
7335 if (!end) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007336 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007337 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007338 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007339 HistoryItem cur = mHistoryIterator;
7340 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007341 if (!mReadOverflow && !end) {
7342 Slog.w(TAG, "Old history ends before new history!");
7343 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007344 return false;
7345 }
7346 out.setTo(cur);
7347 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007348 if (!mReadOverflow) {
7349 if (end) {
7350 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007351 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn8c841092013-06-24 13:46:13 -07007352 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007353 pw.println("Histories differ!");
7354 pw.println("Old history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007355 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007356 pw.println("New history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007357 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false,
7358 true);
Dianne Hackborn8c841092013-06-24 13:46:13 -07007359 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007360 }
7361 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007362 return true;
7363 }
7364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007365 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007366 public void finishIteratingOldHistoryLocked() {
7367 mIteratingHistory = false;
7368 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007369 mHistoryIterator = null;
7370 }
7371
7372 public int getHistoryTotalSize() {
7373 return MAX_HISTORY_BUFFER;
7374 }
7375
7376 public int getHistoryUsedSize() {
7377 return mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007378 }
7379
7380 @Override
7381 public boolean startIteratingHistoryLocked() {
7382 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
7383 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007384 if (mHistoryBuffer.dataSize() <= 0) {
7385 return false;
7386 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007387 mHistoryBuffer.setDataPosition(0);
7388 mReadOverflow = false;
7389 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007390 mReadHistoryStrings = new String[mHistoryTagPool.size()];
7391 mReadHistoryUids = new int[mHistoryTagPool.size()];
7392 mReadHistoryChars = 0;
7393 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
7394 final HistoryTag tag = ent.getKey();
7395 final int idx = ent.getValue();
7396 mReadHistoryStrings[idx] = tag.string;
7397 mReadHistoryUids[idx] = tag.uid;
7398 mReadHistoryChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08007399 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007400 return true;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007401 }
7402
7403 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08007404 public int getHistoryStringPoolSize() {
7405 return mReadHistoryStrings.length;
7406 }
7407
7408 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007409 public int getHistoryStringPoolBytes() {
7410 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
7411 // Each string character is 2 bytes.
7412 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
7413 }
7414
7415 @Override
7416 public String getHistoryTagPoolString(int index) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08007417 return mReadHistoryStrings[index];
7418 }
7419
7420 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007421 public int getHistoryTagPoolUid(int index) {
7422 return mReadHistoryUids[index];
7423 }
7424
7425 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007426 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007427 final int pos = mHistoryBuffer.dataPosition();
7428 if (pos == 0) {
7429 out.clear();
7430 }
7431 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007432 if (end) {
7433 return false;
7434 }
7435
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007436 final long lastRealtime = out.time;
7437 final long lastWalltime = out.currentTime;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007438 readHistoryDelta(mHistoryBuffer, out);
Dianne Hackborn37de0982014-05-09 09:32:18 -07007439 if (out.cmd != HistoryItem.CMD_CURRENT_TIME
7440 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007441 out.currentTime = lastWalltime + (out.time - lastRealtime);
7442 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007443 return true;
7444 }
7445
7446 @Override
7447 public void finishIteratingHistoryLocked() {
7448 mIteratingHistory = false;
7449 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn099bc622014-01-22 13:39:16 -08007450 mReadHistoryStrings = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007451 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007452
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007453 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07007454 public long getHistoryBaseTime() {
7455 return mHistoryBaseTime;
7456 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007457
Dianne Hackbornb5e31652010-09-07 12:13:55 -07007458 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007459 public int getStartCount() {
7460 return mStartCount;
7461 }
7462
7463 public boolean isOnBattery() {
7464 return mOnBattery;
7465 }
7466
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007467 public boolean isCharging() {
7468 return mCharging;
7469 }
7470
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007471 public boolean isScreenOn() {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007472 return mScreenState == Display.STATE_ON;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007473 }
7474
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007475 void initTimes(long uptime, long realtime) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007476 mStartClockTime = System.currentTimeMillis();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007477 mOnBatteryTimeBase.init(uptime, realtime);
7478 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
Dianne Hackborn4590e522014-03-24 13:36:46 -07007479 mRealtime = 0;
7480 mUptime = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007481 mRealtimeStart = realtime;
Dianne Hackborn4590e522014-03-24 13:36:46 -07007482 mUptimeStart = uptime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007483 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007484
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007485 void initDischarge() {
7486 mLowDischargeAmountSinceCharge = 0;
7487 mHighDischargeAmountSinceCharge = 0;
7488 mDischargeAmountScreenOn = 0;
7489 mDischargeAmountScreenOnSinceCharge = 0;
7490 mDischargeAmountScreenOff = 0;
7491 mDischargeAmountScreenOffSinceCharge = 0;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007492 mDischargeStepTracker.init();
7493 mChargeStepTracker.init();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007494 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007495
7496 public void resetAllStatsCmdLocked() {
7497 resetAllStatsLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07007498 final long mSecUptime = SystemClock.uptimeMillis();
7499 long uptime = mSecUptime * 1000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007500 long mSecRealtime = SystemClock.elapsedRealtime();
7501 long realtime = mSecRealtime * 1000;
7502 mDischargeStartLevel = mHistoryCur.batteryLevel;
7503 pullPendingStateUpdatesLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07007504 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007505 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
7506 = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007507 mOnBatteryTimeBase.reset(uptime, realtime);
7508 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
7509 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007510 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007511 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
7512 mDischargeScreenOffUnplugLevel = 0;
7513 } else {
7514 mDischargeScreenOnUnplugLevel = 0;
7515 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
7516 }
7517 mDischargeAmountScreenOn = 0;
7518 mDischargeAmountScreenOff = 0;
7519 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07007520 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007521 }
7522
7523 private void resetAllStatsLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007524 mStartCount = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007525 initTimes(SystemClock.uptimeMillis() * 1000, SystemClock.elapsedRealtime() * 1000);
7526 mScreenOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007527 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007528 mScreenBrightnessTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007529 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007530 mInteractiveTimer.reset(false);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07007531 mPowerSaveModeEnabledTimer.reset(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07007532 mLongestLightIdleTime = 0;
7533 mLongestFullIdleTime = 0;
7534 mDeviceIdleModeLightTimer.reset(false);
7535 mDeviceIdleModeFullTimer.reset(false);
7536 mDeviceLightIdlingTimer.reset(false);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007537 mDeviceIdlingTimer.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007538 mPhoneOnTimer.reset(false);
7539 mAudioOnTimer.reset(false);
7540 mVideoOnTimer.reset(false);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07007541 mFlashlightOnTimer.reset(false);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07007542 mCameraOnTimer.reset(false);
Wink Saville52840902011-02-18 12:40:47 -08007543 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007544 mPhoneSignalStrengthsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007545 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007546 mPhoneSignalScanningTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007547 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007548 mPhoneDataConnectionsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007549 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007550 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007551 mNetworkByteActivityCounters[i].reset(false);
7552 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007553 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007554 mMobileRadioActiveTimer.reset(false);
7555 mMobileRadioActivePerAppTimer.reset(false);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007556 mMobileRadioActiveAdjustedTime.reset(false);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007557 mMobileRadioActiveUnknownTime.reset(false);
7558 mMobileRadioActiveUnknownCount.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007559 mWifiOnTimer.reset(false);
7560 mGlobalWifiRunningTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007561 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007562 mWifiStateTimer[i].reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007563 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07007564 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
7565 mWifiSupplStateTimer[i].reset(false);
7566 }
7567 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
7568 mWifiSignalStrengthsTimer[i].reset(false);
7569 }
Adam Lesinski33dac552015-03-09 15:24:48 -07007570 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
7571 mBluetoothActivityCounters[i].reset(false);
7572 mWifiActivityCounters[i].reset(false);
7573 }
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007574 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007575
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007576 for (int i=0; i<mUidStats.size(); i++) {
7577 if (mUidStats.valueAt(i).reset()) {
7578 mUidStats.remove(mUidStats.keyAt(i));
7579 i--;
7580 }
7581 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007582
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007583 if (mKernelWakelockStats.size() > 0) {
7584 for (SamplingTimer timer : mKernelWakelockStats.values()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007585 mOnBatteryScreenOffTimeBase.remove(timer);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007586 }
7587 mKernelWakelockStats.clear();
7588 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007589
7590 if (mWakeupReasonStats.size() > 0) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07007591 for (SamplingTimer timer : mWakeupReasonStats.values()) {
7592 mOnBatteryTimeBase.remove(timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007593 }
7594 mWakeupReasonStats.clear();
7595 }
7596
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007597 mLastHistoryStepDetails = null;
7598 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0;
7599 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0;
7600 mLastStepCpuUserTime = mCurStepCpuUserTime = 0;
7601 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0;
7602 mLastStepStatUserTime = mCurStepStatUserTime = 0;
7603 mLastStepStatSystemTime = mCurStepStatSystemTime = 0;
7604 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0;
7605 mLastStepStatIrqTime = mCurStepStatIrqTime = 0;
7606 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0;
7607 mLastStepStatIdleTime = mCurStepStatIdleTime = 0;
7608
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007609 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007610
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007611 clearHistoryLocked();
7612 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007613
Dianne Hackborn40c87252014-03-19 16:55:40 -07007614 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007615 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007616 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) {
7617 // Not recording process starts/stops.
7618 continue;
7619 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07007620 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007621 if (active == null) {
7622 continue;
7623 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07007624 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
7625 SparseIntArray uids = ent.getValue();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007626 for (int j=0; j<uids.size(); j++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07007627 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
7628 uids.keyAt(j));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007629 }
7630 }
7631 }
7632 }
7633
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007634 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007635 if (oldScreenOn) {
7636 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
7637 if (diff > 0) {
7638 mDischargeAmountScreenOn += diff;
7639 mDischargeAmountScreenOnSinceCharge += diff;
7640 }
7641 } else {
7642 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
7643 if (diff > 0) {
7644 mDischargeAmountScreenOff += diff;
7645 mDischargeAmountScreenOffSinceCharge += diff;
7646 }
7647 }
7648 if (newScreenOn) {
7649 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
7650 mDischargeScreenOffUnplugLevel = 0;
7651 } else {
7652 mDischargeScreenOnUnplugLevel = 0;
7653 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
7654 }
7655 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007656
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007657 public void pullPendingStateUpdatesLocked() {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08007658 if (mOnBatteryInternal) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007659 final boolean screenOn = mScreenState == Display.STATE_ON;
7660 updateDischargeScreenLevelsLocked(screenOn, screenOn);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08007661 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007662 }
7663
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007664 private String[] mMobileIfaces = EmptyArray.STRING;
7665 private String[] mWifiIfaces = EmptyArray.STRING;
7666
7667 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
7668
7669 private static final int NETWORK_STATS_LAST = 0;
7670 private static final int NETWORK_STATS_NEXT = 1;
7671 private static final int NETWORK_STATS_DELTA = 2;
7672
7673 private final NetworkStats[] mMobileNetworkStats = new NetworkStats[] {
7674 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7675 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7676 new NetworkStats(SystemClock.elapsedRealtime(), 50)
7677 };
7678
7679 private final NetworkStats[] mWifiNetworkStats = new NetworkStats[] {
7680 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7681 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7682 new NetworkStats(SystemClock.elapsedRealtime(), 50)
7683 };
7684
7685 /**
7686 * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer
7687 * as a buffer of NetworkStats objects to cycle through when computing deltas.
7688 */
7689 private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces,
7690 NetworkStats[] networkStatsBuffer)
7691 throws IOException {
7692 if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED,
7693 false)) {
7694 return null;
7695 }
7696
7697 final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL,
7698 ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]);
7699 networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats,
7700 networkStatsBuffer[NETWORK_STATS_LAST], null, null,
7701 networkStatsBuffer[NETWORK_STATS_DELTA]);
7702 networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST];
7703 networkStatsBuffer[NETWORK_STATS_LAST] = stats;
7704 return networkStatsBuffer[NETWORK_STATS_DELTA];
7705 }
7706
7707 /**
7708 * Distribute WiFi energy info and network traffic to apps.
7709 * @param info The energy information from the WiFi controller.
7710 */
7711 public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -07007712 if (DEBUG_ENERGY) {
7713 Slog.d(TAG, "Updating wifi stats");
7714 }
7715
Adam Lesinskie08af192015-03-25 16:42:59 -07007716 final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
7717 NetworkStats delta = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007718 try {
Adam Lesinskie08af192015-03-25 16:42:59 -07007719 if (!ArrayUtils.isEmpty(mWifiIfaces)) {
7720 delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats);
7721 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007722 } catch (IOException e) {
7723 Slog.wtf(TAG, "Failed to get wifi network stats", e);
7724 return;
7725 }
7726
7727 if (!mOnBatteryInternal) {
7728 return;
7729 }
7730
Adam Lesinskie08af192015-03-25 16:42:59 -07007731 SparseLongArray rxPackets = new SparseLongArray();
7732 SparseLongArray txPackets = new SparseLongArray();
7733 long totalTxPackets = 0;
7734 long totalRxPackets = 0;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007735 if (delta != null) {
7736 final int size = delta.size();
7737 for (int i = 0; i < size; i++) {
7738 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
7739
Adam Lesinskie08af192015-03-25 16:42:59 -07007740 if (DEBUG_ENERGY) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007741 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
Adam Lesinskie08af192015-03-25 16:42:59 -07007742 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
7743 + " txPackets=" + entry.txPackets);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007744 }
7745
7746 if (entry.rxBytes == 0 || entry.txBytes == 0) {
7747 continue;
7748 }
7749
7750 final Uid u = getUidStatsLocked(mapUid(entry.uid));
Adam Lesinskiba88e682015-12-08 12:06:55 -08007751 if (entry.rxBytes != 0) {
7752 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
7753 entry.rxPackets);
7754 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
7755 entry.rxBytes);
7756 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
7757 entry.rxPackets);
Adam Lesinskie08af192015-03-25 16:42:59 -07007758
Adam Lesinskiba88e682015-12-08 12:06:55 -08007759 rxPackets.put(u.getUid(), entry.rxPackets);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007760
Adam Lesinskiba88e682015-12-08 12:06:55 -08007761 // Sum the total number of packets so that the Rx Power can
7762 // be evenly distributed amongst the apps.
7763 totalRxPackets += entry.rxPackets;
7764 }
7765
7766 if (entry.txBytes != 0) {
7767 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
7768 entry.txPackets);
7769 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
7770 entry.txBytes);
7771 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
7772 entry.txPackets);
7773
7774 txPackets.put(u.getUid(), entry.txPackets);
7775
7776 // Sum the total number of packets so that the Tx Power can
7777 // be evenly distributed amongst the apps.
7778 totalTxPackets += entry.txPackets;
7779 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007780 }
7781 }
7782
7783 if (info != null) {
Adam Lesinski17390762015-04-10 13:17:47 -07007784 mHasWifiEnergyReporting = true;
7785
Adam Lesinskie08af192015-03-25 16:42:59 -07007786 // Measured in mAms
7787 final long txTimeMs = info.getControllerTxTimeMillis();
7788 final long rxTimeMs = info.getControllerRxTimeMillis();
7789 final long idleTimeMs = info.getControllerIdleTimeMillis();
7790 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
7791
7792 long leftOverRxTimeMs = rxTimeMs;
Mitchell Willsf9016492015-07-29 17:47:44 -07007793 long leftOverTxTimeMs = txTimeMs;
Adam Lesinskie08af192015-03-25 16:42:59 -07007794
7795 if (DEBUG_ENERGY) {
7796 Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
7797 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
7798 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
7799 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
7800 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms");
7801 }
7802
7803 long totalWifiLockTimeMs = 0;
7804 long totalScanTimeMs = 0;
7805
7806 // On the first pass, collect some totals so that we can normalize power
7807 // calculations if we need to.
7808 final int uidStatsSize = mUidStats.size();
7809 for (int i = 0; i < uidStatsSize; i++) {
7810 final Uid uid = mUidStats.valueAt(i);
7811
7812 // Sum the total scan power for all apps.
7813 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
7814 elapsedRealtimeMs * 1000) / 1000;
7815
7816 // Sum the total time holding wifi lock for all apps.
7817 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
7818 elapsedRealtimeMs * 1000) / 1000;
7819 }
7820
7821 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
7822 Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
7823 + rxTimeMs + " ms). Normalizing scan time.");
7824 }
Mitchell Willsf9016492015-07-29 17:47:44 -07007825 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) {
7826 Slog.d(TAG, " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > "
7827 + txTimeMs + " ms). Normalizing scan time.");
7828 }
Adam Lesinskie08af192015-03-25 16:42:59 -07007829
7830 // Actually assign and distribute power usage to apps.
7831 for (int i = 0; i < uidStatsSize; i++) {
7832 final Uid uid = mUidStats.valueAt(i);
7833
7834 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
7835 elapsedRealtimeMs * 1000) / 1000;
7836 if (scanTimeSinceMarkMs > 0) {
7837 // Set the new mark so that next time we get new data since this point.
7838 uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
7839
Mitchell Willsf9016492015-07-29 17:47:44 -07007840 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs;
7841 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs;
7842
7843 // Our total scan time is more than the reported Tx/Rx time.
7844 // This is possible because the cost of a scan is approximate.
7845 // Let's normalize the result so that we evenly blame each app
7846 // scanning.
7847 //
7848 // This means that we may have apps that transmitted/received packets not be
7849 // blamed for this, but this is fine as scans are relatively more expensive.
Adam Lesinskie08af192015-03-25 16:42:59 -07007850 if (totalScanTimeMs > rxTimeMs) {
Mitchell Willsf9016492015-07-29 17:47:44 -07007851 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) /
7852 totalScanTimeMs;
7853 }
7854 if (totalScanTimeMs > txTimeMs) {
7855 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) /
7856 totalScanTimeMs;
Adam Lesinskie08af192015-03-25 16:42:59 -07007857 }
7858
7859 if (DEBUG_ENERGY) {
Mitchell Willsf9016492015-07-29 17:47:44 -07007860 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:"
7861 + scanRxTimeSinceMarkMs + " ms Tx:"
7862 + scanTxTimeSinceMarkMs + " ms)");
Adam Lesinskie08af192015-03-25 16:42:59 -07007863 }
Mitchell Willsf9016492015-07-29 17:47:44 -07007864 uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanRxTimeSinceMarkMs);
7865 uid.noteWifiControllerActivityLocked(CONTROLLER_TX_TIME, scanTxTimeSinceMarkMs);
7866 leftOverRxTimeMs -= scanRxTimeSinceMarkMs;
7867 leftOverTxTimeMs -= scanTxTimeSinceMarkMs;
Adam Lesinskie08af192015-03-25 16:42:59 -07007868 }
7869
7870 // Distribute evenly the power consumed while Idle to each app holding a WiFi
7871 // lock.
7872 final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
7873 elapsedRealtimeMs * 1000) / 1000;
7874 if (wifiLockTimeSinceMarkMs > 0) {
7875 // Set the new mark so that next time we get new data since this point.
7876 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
7877
7878 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
7879 / totalWifiLockTimeMs;
7880 if (DEBUG_ENERGY) {
7881 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": "
7882 + myIdleTimeMs + " ms");
7883 }
7884 uid.noteWifiControllerActivityLocked(CONTROLLER_IDLE_TIME, myIdleTimeMs);
7885 }
7886 }
7887
7888 if (DEBUG_ENERGY) {
7889 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
Mitchell Willsf9016492015-07-29 17:47:44 -07007890 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms");
Adam Lesinskie08af192015-03-25 16:42:59 -07007891 }
7892
Mitchell Willsf9016492015-07-29 17:47:44 -07007893 // Distribute the remaining Tx power appropriately between all apps that transmitted
7894 // packets.
Adam Lesinskie08af192015-03-25 16:42:59 -07007895 for (int i = 0; i < txPackets.size(); i++) {
7896 final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
Mitchell Willsf9016492015-07-29 17:47:44 -07007897 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets;
Adam Lesinskie08af192015-03-25 16:42:59 -07007898 if (DEBUG_ENERGY) {
7899 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
7900 }
7901 uid.noteWifiControllerActivityLocked(CONTROLLER_TX_TIME, myTxTimeMs);
7902 }
7903
7904 // Distribute the remaining Rx power appropriately between all apps that received
7905 // packets.
7906 for (int i = 0; i < rxPackets.size(); i++) {
7907 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i));
7908 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets;
7909 if (DEBUG_ENERGY) {
7910 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
7911 }
7912 uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, myRxTimeMs);
7913 }
7914
7915 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
7916
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007917 // Update WiFi controller stats.
7918 mWifiActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
7919 info.getControllerRxTimeMillis());
7920 mWifiActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
7921 info.getControllerTxTimeMillis());
7922 mWifiActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
7923 info.getControllerIdleTimeMillis());
Adam Lesinskie08af192015-03-25 16:42:59 -07007924
Adam Lesinski8576cf92015-06-09 12:48:25 -07007925 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
7926 final double opVolt = mPowerProfile.getAveragePower(
7927 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
7928 if (opVolt != 0) {
7929 // We store the power drain as mAms.
Adam Lesinskie283d332015-04-16 12:29:25 -07007930 mWifiActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked(
Adam Lesinski8576cf92015-06-09 12:48:25 -07007931 (long)(info.getControllerEnergyUsed() / opVolt));
Adam Lesinskie08af192015-03-25 16:42:59 -07007932 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007933 }
7934 }
7935
7936 /**
7937 * Distribute Cell radio energy info and network traffic to apps.
7938 */
Adam Lesinskie08af192015-03-25 16:42:59 -07007939 public void updateMobileRadioStateLocked(final long elapsedRealtimeMs) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -07007940 if (DEBUG_ENERGY) {
7941 Slog.d(TAG, "Updating mobile radio stats");
7942 }
7943
Adam Lesinskie08af192015-03-25 16:42:59 -07007944 NetworkStats delta = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007945 try {
Adam Lesinskie08af192015-03-25 16:42:59 -07007946 if (!ArrayUtils.isEmpty(mMobileIfaces)) {
7947 delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats);
7948 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007949 } catch (IOException e) {
7950 Slog.wtf(TAG, "Failed to get mobile network stats", e);
7951 return;
7952 }
7953
7954 if (delta == null || !mOnBatteryInternal) {
7955 return;
7956 }
7957
Adam Lesinskie08af192015-03-25 16:42:59 -07007958 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
7959 elapsedRealtimeMs * 1000);
7960 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007961 long totalPackets = delta.getTotalPackets();
7962
7963 final int size = delta.size();
7964 for (int i = 0; i < size; i++) {
7965 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
7966
Adam Lesinskie08af192015-03-25 16:42:59 -07007967 if (entry.rxBytes == 0 || entry.txBytes == 0) {
7968 continue;
7969 }
7970
7971 if (DEBUG_ENERGY) {
7972 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
7973 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
7974 + " txPackets=" + entry.txPackets);
7975 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007976
7977 final Uid u = getUidStatsLocked(mapUid(entry.uid));
7978 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
7979 entry.rxPackets);
7980 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
7981 entry.txPackets);
7982
7983 if (radioTime > 0) {
7984 // Distribute total radio active time in to this app.
7985 long appPackets = entry.rxPackets + entry.txPackets;
7986 long appRadioTime = (radioTime*appPackets)/totalPackets;
7987 u.noteMobileRadioActiveTimeLocked(appRadioTime);
7988 // Remove this app from the totals, so that we don't lose any time
7989 // due to rounding.
7990 radioTime -= appRadioTime;
7991 totalPackets -= appPackets;
7992 }
7993
7994 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
7995 entry.rxBytes);
7996 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
7997 entry.txBytes);
7998 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
7999 entry.rxPackets);
8000 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
8001 entry.txPackets);
8002 }
8003
8004 if (radioTime > 0) {
8005 // Whoops, there is some radio time we can't blame on an app!
8006 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
8007 mMobileRadioActiveUnknownCount.addCountLocked(1);
8008 }
8009 }
8010
8011 /**
8012 * Distribute Bluetooth energy info and network traffic to apps.
8013 * @param info The energy information from the bluetooth controller.
8014 */
8015 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -07008016 if (DEBUG_ENERGY) {
Adam Lesinski50e47602015-12-04 17:04:54 -08008017 Slog.d(TAG, "Updating bluetooth stats: " + info);
Adam Lesinskia7c90c82015-06-18 14:52:24 -07008018 }
8019
Adam Lesinski719e61f2015-05-15 15:49:24 -07008020 if (info != null && mOnBatteryInternal) {
Adam Lesinski17390762015-04-10 13:17:47 -07008021 mHasBluetoothEnergyReporting = true;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008022 mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
8023 info.getControllerRxTimeMillis());
8024 mBluetoothActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
8025 info.getControllerTxTimeMillis());
8026 mBluetoothActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
8027 info.getControllerIdleTimeMillis());
Adam Lesinskie283d332015-04-16 12:29:25 -07008028
Adam Lesinski8576cf92015-06-09 12:48:25 -07008029 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
8030 final double opVolt = mPowerProfile.getAveragePower(
8031 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
8032 if (opVolt != 0) {
8033 // We store the power drain as mAms.
Adam Lesinskie283d332015-04-16 12:29:25 -07008034 mBluetoothActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked(
Adam Lesinski8576cf92015-06-09 12:48:25 -07008035 (long) (info.getControllerEnergyUsed() / opVolt));
Adam Lesinskie283d332015-04-16 12:29:25 -07008036 }
Adam Lesinski50e47602015-12-04 17:04:54 -08008037
8038 final UidTraffic[] uidTraffic = info.getUidTraffic();
8039 final int numUids = uidTraffic != null ? uidTraffic.length : 0;
8040 for (int i = 0; i < numUids; i++) {
8041 final UidTraffic traffic = uidTraffic[i];
8042
8043 // Add to the global counters.
8044 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(
8045 traffic.getRxBytes());
8046 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(
8047 traffic.getTxBytes());
8048
8049 // Add to the UID counters.
8050 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()));
8051 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, traffic.getRxBytes(), 0);
8052 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, traffic.getTxBytes(), 0);
8053 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008054 }
8055 }
8056
8057 /**
8058 * Read and distribute kernel wake lock use across apps.
8059 */
8060 public void updateKernelWakelocksLocked() {
8061 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
8062 mTmpWakelockStats);
8063 if (wakelockStats == null) {
8064 // Not crashing might make board bringup easier.
8065 Slog.w(TAG, "Couldn't get kernel wake lock stats");
8066 return;
8067 }
8068
Adam Lesinskifbabe7d2015-08-03 14:37:38 -07008069 // Record whether we've seen a non-zero time (for debugging b/22716723).
8070 boolean seenNonZeroTime = false;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008071 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
8072 String name = ent.getKey();
8073 KernelWakelockStats.Entry kws = ent.getValue();
8074
8075 SamplingTimer kwlt = mKernelWakelockStats.get(name);
8076 if (kwlt == null) {
8077 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
8078 true /* track reported val */);
8079 mKernelWakelockStats.put(name, kwlt);
8080 }
8081 kwlt.updateCurrentReportedCount(kws.mCount);
8082 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
8083 kwlt.setUpdateVersion(kws.mVersion);
Adam Lesinskifbabe7d2015-08-03 14:37:38 -07008084
8085 if (kws.mVersion != wakelockStats.kernelWakelockVersion)
8086 seenNonZeroTime |= kws.mTotalTime > 0;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008087 }
8088
Adam Lesinskifbabe7d2015-08-03 14:37:38 -07008089 int numWakelocksSetStale = 0;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008090 if (wakelockStats.size() != mKernelWakelockStats.size()) {
8091 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
8092 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
8093 SamplingTimer st = ent.getValue();
8094 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
8095 st.setStale();
Adam Lesinskifbabe7d2015-08-03 14:37:38 -07008096 numWakelocksSetStale++;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008097 }
8098 }
8099 }
Adam Lesinskifbabe7d2015-08-03 14:37:38 -07008100
8101 if (!seenNonZeroTime) {
8102 Slog.wtf(TAG, "All kernel wakelocks had time of zero");
8103 }
8104
8105 if (numWakelocksSetStale == mKernelWakelockStats.size()) {
8106 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" +
8107 wakelockStats.kernelWakelockVersion);
8108 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008109 }
8110
Adam Lesinski72478f02015-06-17 15:39:43 -07008111 // We use an anonymous class to access these variables,
8112 // so they can't live on the stack or they'd have to be
8113 // final MutableLong objects (more allocations).
8114 // Used in updateCpuTimeLocked().
8115 long mTempTotalCpuUserTimeUs;
8116 long mTempTotalCpuSystemTimeUs;
8117
Adam Lesinski06af1fa2015-05-05 17:35:35 -07008118 /**
Adam Lesinski72478f02015-06-17 15:39:43 -07008119 * Read and distribute CPU usage across apps. If their are partial wakelocks being held
8120 * and we are on battery with screen off, we give more of the cpu time to those apps holding
8121 * wakelocks. If the screen is on, we just assign the actual cpu time an app used.
Adam Lesinski06af1fa2015-05-05 17:35:35 -07008122 */
Adam Lesinski72478f02015-06-17 15:39:43 -07008123 public void updateCpuTimeLocked() {
Adam Lesinski52290c9c2015-09-21 16:54:52 -07008124 if (mPowerProfile == null) {
8125 return;
8126 }
8127
Adam Lesinski72478f02015-06-17 15:39:43 -07008128 if (DEBUG_ENERGY_CPU) {
8129 Slog.d(TAG, "!Cpu updating!");
8130 }
8131
8132 // Holding a wakelock costs more than just using the cpu.
8133 // Currently, we assign only half the cpu time to an app that is running but
8134 // not holding a wakelock. The apps holding wakelocks get the rest of the blame.
8135 // If no app is holding a wakelock, then the distribution is normal.
8136 final int wakelockWeight = 50;
8137
Adam Lesinski6832f392015-09-05 18:05:40 -07008138 // Read the time spent for each cluster at various cpu frequencies.
8139 final long[][] clusterSpeeds = new long[mKernelCpuSpeedReaders.length][];
8140 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
8141 clusterSpeeds[cluster] = mKernelCpuSpeedReaders[cluster].readDelta();
8142 }
Adam Lesinski72478f02015-06-17 15:39:43 -07008143
8144 int numWakelocks = 0;
8145
8146 // Calculate how many wakelocks we have to distribute amongst. The system is excluded.
8147 // Only distribute cpu power to wakelocks if the screen is off and we're on battery.
8148 final int numPartialTimers = mPartialTimers.size();
8149 if (mOnBatteryScreenOffTimeBase.isRunning()) {
8150 for (int i = 0; i < numPartialTimers; i++) {
8151 final StopwatchTimer timer = mPartialTimers.get(i);
8152 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
8153 // Since the collection and blaming of wakelocks can be scheduled to run after
8154 // some delay, the mPartialTimers list may have new entries. We can't blame
8155 // the newly added timer for past cpu time, so we only consider timers that
8156 // were present for one round of collection. Once a timer has gone through
8157 // a round of collection, its mInList field is set to true.
8158 numWakelocks++;
Adam Lesinski06af1fa2015-05-05 17:35:35 -07008159 }
Adam Lesinski72478f02015-06-17 15:39:43 -07008160 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07008161 }
Adam Lesinski72478f02015-06-17 15:39:43 -07008162
8163 final int numWakelocksF = numWakelocks;
8164 mTempTotalCpuUserTimeUs = 0;
8165 mTempTotalCpuSystemTimeUs = 0;
8166
8167 // Read the CPU data for each UID. This will internally generate a snapshot so next time
8168 // we read, we get a delta. If we are to distribute the cpu time, then do so. Otherwise
8169 // we just ignore the data.
8170 final long startTimeMs = SystemClock.elapsedRealtime();
8171 mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null :
8172 new KernelUidCpuTimeReader.Callback() {
8173 @Override
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07008174 public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs,
8175 long powerMaUs) {
Adam Lesinski72478f02015-06-17 15:39:43 -07008176 final Uid u = getUidStatsLocked(mapUid(uid));
8177
8178 // Accumulate the total system and user time.
8179 mTempTotalCpuUserTimeUs += userTimeUs;
8180 mTempTotalCpuSystemTimeUs += systemTimeUs;
8181
8182 StringBuilder sb = null;
8183 if (DEBUG_ENERGY_CPU) {
8184 sb = new StringBuilder();
8185 sb.append(" got time for uid=").append(u.mUid).append(": u=");
8186 TimeUtils.formatDuration(userTimeUs / 1000, sb);
8187 sb.append(" s=");
8188 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07008189 sb.append(" p=").append(powerMaUs / 1000).append("mAms\n");
Adam Lesinski72478f02015-06-17 15:39:43 -07008190 }
8191
8192 if (numWakelocksF > 0) {
8193 // We have wakelocks being held, so only give a portion of the
8194 // time to the process. The rest will be distributed among wakelock
8195 // holders.
8196 userTimeUs = (userTimeUs * wakelockWeight) / 100;
8197 systemTimeUs = (systemTimeUs * wakelockWeight) / 100;
8198 }
8199
8200 if (sb != null) {
8201 sb.append(" adding to uid=").append(u.mUid).append(": u=");
8202 TimeUtils.formatDuration(userTimeUs / 1000, sb);
8203 sb.append(" s=");
8204 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07008205 sb.append(" p=").append(powerMaUs / 1000).append("mAms");
Adam Lesinski72478f02015-06-17 15:39:43 -07008206 Slog.d(TAG, sb.toString());
8207 }
8208
8209 u.mUserCpuTime.addCountLocked(userTimeUs);
8210 u.mSystemCpuTime.addCountLocked(systemTimeUs);
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07008211 u.mCpuPower.addCountLocked(powerMaUs);
Adam Lesinski72478f02015-06-17 15:39:43 -07008212
8213 // Add the cpu speeds to this UID. These are used as a ratio
8214 // for computing the power this UID used.
Adam Lesinski52290c9c2015-09-21 16:54:52 -07008215 final int numClusters = mPowerProfile.getNumCpuClusters();
8216 if (u.mCpuClusterSpeed == null || u.mCpuClusterSpeed.length !=
8217 numClusters) {
8218 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][];
Adam Lesinski6832f392015-09-05 18:05:40 -07008219 }
8220
8221 for (int cluster = 0; cluster < clusterSpeeds.length; cluster++) {
Adam Lesinski52290c9c2015-09-21 16:54:52 -07008222 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(
8223 cluster);
8224 if (u.mCpuClusterSpeed[cluster] == null || speedsInCluster !=
8225 u.mCpuClusterSpeed[cluster].length) {
Adam Lesinski6832f392015-09-05 18:05:40 -07008226 u.mCpuClusterSpeed[cluster] =
Adam Lesinski52290c9c2015-09-21 16:54:52 -07008227 new LongSamplingCounter[speedsInCluster];
Adam Lesinski72478f02015-06-17 15:39:43 -07008228 }
Adam Lesinski6832f392015-09-05 18:05:40 -07008229
8230 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeed[cluster];
8231 for (int speed = 0; speed < clusterSpeeds[cluster].length; speed++) {
8232 if (cpuSpeeds[speed] == null) {
8233 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
8234 }
8235 cpuSpeeds[speed].addCountLocked(clusterSpeeds[cluster][speed]);
8236 }
Adam Lesinski72478f02015-06-17 15:39:43 -07008237 }
8238 }
8239 });
8240
8241 if (DEBUG_ENERGY_CPU) {
8242 Slog.d(TAG, "Reading cpu stats took " + (SystemClock.elapsedRealtime() - startTimeMs) +
8243 " ms");
8244 }
8245
8246 if (mOnBatteryInternal && numWakelocks > 0) {
8247 // Distribute a portion of the total cpu time to wakelock holders.
8248 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - wakelockWeight)) / 100;
8249 mTempTotalCpuSystemTimeUs =
8250 (mTempTotalCpuSystemTimeUs * (100 - wakelockWeight)) / 100;
8251
8252 for (int i = 0; i < numPartialTimers; i++) {
8253 final StopwatchTimer timer = mPartialTimers.get(i);
8254
8255 // The system does not share any blame, as it is usually holding the wakelock
8256 // on behalf of an app.
8257 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
8258 int userTimeUs = (int) (mTempTotalCpuUserTimeUs / numWakelocks);
8259 int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / numWakelocks);
8260
8261 if (DEBUG_ENERGY_CPU) {
8262 StringBuilder sb = new StringBuilder();
8263 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid)
8264 .append(": u=");
8265 TimeUtils.formatDuration(userTimeUs / 1000, sb);
8266 sb.append(" s=");
8267 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
8268 Slog.d(TAG, sb.toString());
8269 }
8270
8271 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs);
8272 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs);
8273
8274 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*");
Adam Lesinski062e66c2015-07-14 12:02:44 -07008275 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000);
Adam Lesinski72478f02015-06-17 15:39:43 -07008276
8277 mTempTotalCpuUserTimeUs -= userTimeUs;
8278 mTempTotalCpuSystemTimeUs -= systemTimeUs;
8279 numWakelocks--;
8280 }
8281 }
8282
8283 if (mTempTotalCpuUserTimeUs > 0 || mTempTotalCpuSystemTimeUs > 0) {
8284 // Anything left over is given to the system.
8285 if (DEBUG_ENERGY_CPU) {
8286 StringBuilder sb = new StringBuilder();
8287 sb.append(" Distributing lost time to system: u=");
8288 TimeUtils.formatDuration(mTempTotalCpuUserTimeUs / 1000, sb);
8289 sb.append(" s=");
8290 TimeUtils.formatDuration(mTempTotalCpuSystemTimeUs / 1000, sb);
8291 Slog.d(TAG, sb.toString());
8292 }
8293
8294 final Uid u = getUidStatsLocked(Process.SYSTEM_UID);
8295 u.mUserCpuTime.addCountLocked(mTempTotalCpuUserTimeUs);
8296 u.mSystemCpuTime.addCountLocked(mTempTotalCpuSystemTimeUs);
8297
8298 final Uid.Proc proc = u.getProcessStatsLocked("*lost*");
Adam Lesinski062e66c2015-07-14 12:02:44 -07008299 proc.addCpuTimeLocked((int) mTempTotalCpuUserTimeUs / 1000,
8300 (int) mTempTotalCpuSystemTimeUs / 1000);
Adam Lesinski72478f02015-06-17 15:39:43 -07008301 }
8302 }
8303
8304 // See if there is a difference in wakelocks between this collection and the last
8305 // collection.
8306 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) {
8307 // No difference, so each timer is now considered for the next collection.
8308 for (int i = 0; i < numPartialTimers; i++) {
8309 mPartialTimers.get(i).mInList = true;
8310 }
8311 } else {
8312 // The lists are different, meaning we added (or removed a timer) since the last
8313 // collection.
8314 final int numLastPartialTimers = mLastPartialTimers.size();
8315 for (int i = 0; i < numLastPartialTimers; i++) {
8316 mLastPartialTimers.get(i).mInList = false;
8317 }
8318 mLastPartialTimers.clear();
8319
8320 // Mark the current timers as gone through a collection.
8321 for (int i = 0; i < numPartialTimers; i++) {
8322 final StopwatchTimer timer = mPartialTimers.get(i);
8323 timer.mInList = true;
8324 mLastPartialTimers.add(timer);
8325 }
8326 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07008327 }
8328
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008329 boolean setChargingLocked(boolean charging) {
8330 if (mCharging != charging) {
8331 mCharging = charging;
8332 if (charging) {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07008333 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008334 } else {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07008335 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008336 }
8337 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING);
8338 return true;
8339 }
8340 return false;
8341 }
8342
Dianne Hackborn40c87252014-03-19 16:55:40 -07008343 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
8344 final int oldStatus, final int level) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008345 boolean doWrite = false;
8346 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
8347 m.arg1 = onBattery ? 1 : 0;
8348 mHandler.sendMessage(m);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008349
Dianne Hackborn40c87252014-03-19 16:55:40 -07008350 final long uptime = mSecUptime * 1000;
8351 final long realtime = mSecRealtime * 1000;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008352 final boolean screenOn = mScreenState == Display.STATE_ON;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008353 if (onBattery) {
8354 // We will reset our status if we are unplugging after the
8355 // battery was last full, or the level is at 100, or
8356 // we have gone through a significant charge (from a very low
8357 // level to a now very high level).
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08008358 boolean reset = false;
Dianne Hackborn9a755432014-05-15 17:05:22 -07008359 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008360 || level >= 90
Dianne Hackbornfb3809c2014-09-29 18:31:22 -07008361 || (mDischargeCurrentLevel < 20 && level >= 80)
8362 || (getHighDischargeAmountSinceCharge() >= 200
8363 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -07008364 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
Dianne Hackbornfb3809c2014-09-29 18:31:22 -07008365 + " dischargeLevel=" + mDischargeCurrentLevel
Dianne Hackborn73d6a822014-09-29 10:52:47 -07008366 + " lowAmount=" + getLowDischargeAmountSinceCharge()
8367 + " highAmount=" + getHighDischargeAmountSinceCharge());
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008368 // Before we write, collect a snapshot of the final aggregated
8369 // stats to be reported in the next checkin. Only do this if we have
8370 // a sufficient amount of data to make it interesting.
8371 if (getLowDischargeAmountSinceCharge() >= 20) {
8372 final Parcel parcel = Parcel.obtain();
8373 writeSummaryToParcel(parcel, true);
8374 BackgroundThread.getHandler().post(new Runnable() {
8375 @Override public void run() {
8376 synchronized (mCheckinFile) {
8377 FileOutputStream stream = null;
8378 try {
8379 stream = mCheckinFile.startWrite();
8380 stream.write(parcel.marshall());
8381 stream.flush();
8382 FileUtils.sync(stream);
8383 stream.close();
8384 mCheckinFile.finishWrite(stream);
8385 } catch (IOException e) {
8386 Slog.w("BatteryStats",
8387 "Error writing checkin battery statistics", e);
8388 mCheckinFile.failWrite(stream);
8389 } finally {
8390 parcel.recycle();
8391 }
8392 }
8393 }
8394 });
8395 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008396 doWrite = true;
8397 resetAllStatsLocked();
8398 mDischargeStartLevel = level;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08008399 reset = true;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008400 mDischargeStepTracker.init();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008401 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008402 if (mCharging) {
8403 setChargingLocked(false);
8404 }
8405 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08008406 mOnBattery = mOnBatteryInternal = true;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008407 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07008408 mMinDischargeStepLevel = level;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008409 mDischargeStepTracker.clearTime();
8410 mDailyDischargeStepTracker.clearTime();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008411 mInitStepMode = mCurStepMode;
8412 mModStepMode = 0;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08008413 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008414 mHistoryCur.batteryLevel = (byte)level;
8415 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
8416 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
8417 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008418 if (reset) {
8419 mRecordingHistory = true;
8420 startRecordingHistory(mSecRealtime, mSecUptime, reset);
8421 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07008422 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008423 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008424 if (screenOn) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008425 mDischargeScreenOnUnplugLevel = level;
8426 mDischargeScreenOffUnplugLevel = 0;
8427 } else {
8428 mDischargeScreenOnUnplugLevel = 0;
8429 mDischargeScreenOffUnplugLevel = level;
8430 }
8431 mDischargeAmountScreenOn = 0;
8432 mDischargeAmountScreenOff = 0;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008433 updateTimeBasesLocked(true, !screenOn, uptime, realtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008434 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008435 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08008436 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08008437 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008438 mHistoryCur.batteryLevel = (byte)level;
8439 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
8440 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
8441 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07008442 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008443 mDischargeCurrentLevel = mDischargePlugLevel = level;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008444 if (level < mDischargeUnplugLevel) {
8445 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
8446 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
8447 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07008448 updateDischargeScreenLevelsLocked(screenOn, screenOn);
8449 updateTimeBasesLocked(false, !screenOn, uptime, realtime);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008450 mChargeStepTracker.init();
Dianne Hackborn260c5022014-04-29 11:23:16 -07008451 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07008452 mMaxChargeStepLevel = level;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008453 mInitStepMode = mCurStepMode;
8454 mModStepMode = 0;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08008455 }
8456 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
8457 if (mFile != null) {
8458 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008459 }
8460 }
8461 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008462
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008463 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
8464 boolean reset) {
8465 mRecordingHistory = true;
8466 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn37de0982014-05-09 09:32:18 -07008467 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
8468 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008469 mHistoryCur);
8470 mHistoryCur.currentTime = 0;
8471 if (reset) {
8472 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
8473 }
8474 }
8475
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07008476 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs,
8477 final long uptimeMs) {
8478 if (mRecordingHistory) {
8479 mHistoryCur.currentTime = currentTime;
8480 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
8481 mHistoryCur);
8482 mHistoryCur.currentTime = 0;
8483 }
8484 }
8485
Dianne Hackborn29cd7f12015-01-08 10:37:05 -08008486 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
8487 if (mRecordingHistory) {
8488 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn29cd7f12015-01-08 10:37:05 -08008489 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN,
8490 mHistoryCur);
8491 mHistoryCur.currentTime = 0;
8492 }
8493 }
8494
Dianne Hackborn0c820db2015-04-14 17:47:34 -07008495 private void scheduleSyncExternalStatsLocked(String reason) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008496 if (mExternalSync != null) {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07008497 mExternalSync.scheduleSync(reason);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008498 }
8499 }
8500
Adam Lesinskia7c90c82015-06-18 14:52:24 -07008501 private void scheduleSyncExternalWifiStatsLocked(String reason) {
8502 if (mExternalSync != null) {
8503 mExternalSync.scheduleWifiSync(reason);
8504 }
8505 }
8506
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008507 // This should probably be exposed in the API, though it's not critical
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008508 public static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008509
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008510 public void setBatteryStateLocked(int status, int health, int plugType, int level,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008511 int temp, int volt) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008512 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
8513 final long uptime = SystemClock.uptimeMillis();
8514 final long elapsedRealtime = SystemClock.elapsedRealtime();
8515 if (!mHaveBatteryLevel) {
8516 mHaveBatteryLevel = true;
8517 // We start out assuming that the device is plugged in (not
8518 // on battery). If our first report is now that we are indeed
8519 // plugged in, then twiddle our state to correctly reflect that
8520 // since we won't be going through the full setOnBattery().
8521 if (onBattery == mOnBattery) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008522 if (onBattery) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008523 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008524 } else {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008525 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008526 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008527 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008528 // Always start out assuming charging, that will be updated later.
Dianne Hackborn0c820db2015-04-14 17:47:34 -07008529 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008530 mHistoryCur.batteryStatus = (byte)status;
8531 mHistoryCur.batteryLevel = (byte)level;
8532 mMaxChargeStepLevel = mMinDischargeStepLevel =
8533 mLastChargeStepLevel = mLastDischargeStepLevel = level;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008534 mLastChargingStateLevel = level;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008535 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
8536 recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
8537 }
8538 int oldStatus = mHistoryCur.batteryStatus;
8539 if (onBattery) {
8540 mDischargeCurrentLevel = level;
8541 if (!mRecordingHistory) {
8542 mRecordingHistory = true;
8543 startRecordingHistory(elapsedRealtime, uptime, true);
8544 }
8545 } else if (level < 96) {
8546 if (!mRecordingHistory) {
8547 mRecordingHistory = true;
8548 startRecordingHistory(elapsedRealtime, uptime, true);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008549 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008550 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008551 mCurrentBatteryLevel = level;
8552 if (mDischargePlugLevel < 0) {
8553 mDischargePlugLevel = level;
Marco Nelissend8593312009-04-30 14:45:06 -07008554 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008555 if (onBattery != mOnBattery) {
8556 mHistoryCur.batteryLevel = (byte)level;
8557 mHistoryCur.batteryStatus = (byte)status;
8558 mHistoryCur.batteryHealth = (byte)health;
8559 mHistoryCur.batteryPlugType = (byte)plugType;
8560 mHistoryCur.batteryTemperature = (short)temp;
8561 mHistoryCur.batteryVoltage = (char)volt;
8562 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
8563 } else {
8564 boolean changed = false;
8565 if (mHistoryCur.batteryLevel != level) {
8566 mHistoryCur.batteryLevel = (byte)level;
8567 changed = true;
Marco Nelissend8593312009-04-30 14:45:06 -07008568
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008569 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
8570 // which will pull external stats.
Dianne Hackborn0c820db2015-04-14 17:47:34 -07008571 scheduleSyncExternalStatsLocked("battery-level");
Evan Millarc64edde2009-04-18 12:26:32 -07008572 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008573 if (mHistoryCur.batteryStatus != status) {
8574 mHistoryCur.batteryStatus = (byte)status;
8575 changed = true;
8576 }
8577 if (mHistoryCur.batteryHealth != health) {
8578 mHistoryCur.batteryHealth = (byte)health;
8579 changed = true;
8580 }
8581 if (mHistoryCur.batteryPlugType != plugType) {
8582 mHistoryCur.batteryPlugType = (byte)plugType;
8583 changed = true;
8584 }
8585 if (temp >= (mHistoryCur.batteryTemperature+10)
8586 || temp <= (mHistoryCur.batteryTemperature-10)) {
8587 mHistoryCur.batteryTemperature = (short)temp;
8588 changed = true;
8589 }
8590 if (volt > (mHistoryCur.batteryVoltage+20)
8591 || volt < (mHistoryCur.batteryVoltage-20)) {
8592 mHistoryCur.batteryVoltage = (char)volt;
8593 changed = true;
8594 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008595 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
8596 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
8597 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
8598 if (onBattery) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008599 changed |= setChargingLocked(false);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008600 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
8601 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
8602 modeBits, elapsedRealtime);
8603 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
8604 modeBits, elapsedRealtime);
8605 mLastDischargeStepLevel = level;
8606 mMinDischargeStepLevel = level;
8607 mInitStepMode = mCurStepMode;
8608 mModStepMode = 0;
8609 }
8610 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008611 if (level >= 90) {
8612 // If the battery level is at least 90%, always consider the device to be
8613 // charging even if it happens to go down a level.
8614 changed |= setChargingLocked(true);
8615 mLastChargeStepLevel = level;
8616 } if (!mCharging) {
8617 if (mLastChargeStepLevel < level) {
8618 // We have not reporting that we are charging, but the level has now
8619 // gone up, so consider the state to be charging.
8620 changed |= setChargingLocked(true);
8621 mLastChargeStepLevel = level;
8622 }
8623 } else {
8624 if (mLastChargeStepLevel > level) {
8625 // We had reported that the device was charging, but here we are with
8626 // power connected and the level going down. Looks like the current
8627 // power supplied isn't enough, so consider the device to now be
8628 // discharging.
8629 changed |= setChargingLocked(false);
8630 mLastChargeStepLevel = level;
8631 }
8632 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008633 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
8634 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
8635 modeBits, elapsedRealtime);
8636 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
8637 modeBits, elapsedRealtime);
8638 mLastChargeStepLevel = level;
8639 mMaxChargeStepLevel = level;
8640 mInitStepMode = mCurStepMode;
8641 mModStepMode = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07008642 }
8643 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008644 if (changed) {
8645 addHistoryRecordLocked(elapsedRealtime, uptime);
8646 }
Evan Millarc64edde2009-04-18 12:26:32 -07008647 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008648 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
8649 // We don't record history while we are plugged in and fully charged.
8650 // The next time we are unplugged, history will be cleared.
8651 mRecordingHistory = DEBUG;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08008652 }
Adam Lesinski33dac552015-03-09 15:24:48 -07008653 }
8654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655 public long getAwakeTimeBattery() {
8656 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
8657 }
8658
8659 public long getAwakeTimePlugged() {
8660 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
8661 }
8662
8663 @Override
8664 public long computeUptime(long curTime, int which) {
8665 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008666 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008667 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07008668 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008669 }
8670 return 0;
8671 }
8672
8673 @Override
8674 public long computeRealtime(long curTime, int which) {
8675 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008676 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008677 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07008678 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008679 }
8680 return 0;
8681 }
8682
8683 @Override
8684 public long computeBatteryUptime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008685 return mOnBatteryTimeBase.computeUptime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008686 }
8687
8688 @Override
8689 public long computeBatteryRealtime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008690 return mOnBatteryTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008691 }
8692
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008693 @Override
8694 public long computeBatteryScreenOffUptime(long curTime, int which) {
8695 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
8696 }
8697
8698 @Override
8699 public long computeBatteryScreenOffRealtime(long curTime, int which) {
8700 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008701 }
8702
Dianne Hackborn260c5022014-04-29 11:23:16 -07008703 private long computeTimePerLevel(long[] steps, int numSteps) {
8704 // For now we'll do a simple average across all steps.
8705 if (numSteps <= 0) {
8706 return -1;
8707 }
8708 long total = 0;
8709 for (int i=0; i<numSteps; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008710 total += steps[i] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008711 }
8712 return total / numSteps;
8713 /*
8714 long[] buckets = new long[numSteps];
8715 int numBuckets = 0;
8716 int numToAverage = 4;
8717 int i = 0;
8718 while (i < numSteps) {
8719 long totalTime = 0;
8720 int num = 0;
8721 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008722 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008723 num++;
8724 }
8725 buckets[numBuckets] = totalTime / num;
8726 numBuckets++;
8727 numToAverage *= 2;
8728 i += num;
8729 }
8730 if (numBuckets < 1) {
8731 return -1;
8732 }
8733 long averageTime = buckets[numBuckets-1];
8734 for (i=numBuckets-2; i>=0; i--) {
8735 averageTime = (averageTime + buckets[i]) / 2;
8736 }
8737 return averageTime;
8738 */
8739 }
8740
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008741 @Override
8742 public long computeBatteryTimeRemaining(long curTime) {
8743 if (!mOnBattery) {
8744 return -1;
8745 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07008746 /* Simple implementation just looks at the average discharge per level across the
8747 entire sample period.
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008748 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2;
8749 if (discharge < 2) {
8750 return -1;
8751 }
8752 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED);
8753 if (duration < 1000*1000) {
8754 return -1;
8755 }
8756 long usPerLevel = duration/discharge;
8757 return usPerLevel * mCurrentBatteryLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008758 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008759 if (mDischargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008760 return -1;
8761 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008762 long msPerLevel = mDischargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -07008763 if (msPerLevel <= 0) {
8764 return -1;
8765 }
8766 return (msPerLevel * mCurrentBatteryLevel) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008767 }
8768
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008769 @Override
8770 public LevelStepTracker getDischargeLevelStepTracker() {
8771 return mDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008772 }
8773
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008774 @Override
8775 public LevelStepTracker getDailyDischargeLevelStepTracker() {
8776 return mDailyDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008777 }
8778
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008779 @Override
8780 public long computeChargeTimeRemaining(long curTime) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008781 if (mOnBattery) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008782 // Not yet working.
8783 return -1;
8784 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07008785 /* Broken
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008786 int curLevel = mCurrentBatteryLevel;
8787 int plugLevel = mDischargePlugLevel;
8788 if (plugLevel < 0 || curLevel < (plugLevel+1)) {
8789 return -1;
8790 }
8791 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED);
8792 if (duration < 1000*1000) {
8793 return -1;
8794 }
8795 long usPerLevel = duration/(curLevel-plugLevel);
8796 return usPerLevel * (100-curLevel);
Dianne Hackborn260c5022014-04-29 11:23:16 -07008797 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008798 if (mChargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008799 return -1;
8800 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008801 long msPerLevel = mChargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -07008802 if (msPerLevel <= 0) {
8803 return -1;
8804 }
8805 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008806 }
8807
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008808 @Override
8809 public LevelStepTracker getChargeLevelStepTracker() {
8810 return mChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008811 }
8812
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008813 @Override
8814 public LevelStepTracker getDailyChargeLevelStepTracker() {
8815 return mDailyChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008816 }
8817
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008818 @Override
8819 public ArrayList<PackageChange> getDailyPackageChanges() {
8820 return mDailyPackageChanges;
8821 }
8822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008823 long getBatteryUptimeLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008824 return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008825 }
8826
8827 @Override
8828 public long getBatteryUptime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008829 return mOnBatteryTimeBase.getUptime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008830 }
8831
8832 @Override
8833 public long getBatteryRealtime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008834 return mOnBatteryTimeBase.getRealtime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008835 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07008836
The Android Open Source Project10592532009-03-18 17:39:46 -07008837 @Override
Evan Millar633a1742009-04-02 16:36:33 -07008838 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07008839 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07008840 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07008841 }
8842 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008843
Evan Millar633a1742009-04-02 16:36:33 -07008844 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008845 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07008846 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008847
The Android Open Source Project10592532009-03-18 17:39:46 -07008848 @Override
Evan Millar633a1742009-04-02 16:36:33 -07008849 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07008850 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07008851 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07008852 }
8853 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008854
Evan Millar633a1742009-04-02 16:36:33 -07008855 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008856 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07008857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008858
Amith Yamasanie43530a2009-08-21 13:11:37 -07008859 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008860 public int getLowDischargeAmountSinceCharge() {
8861 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008862 int val = mLowDischargeAmountSinceCharge;
8863 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
8864 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
8865 }
8866 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008867 }
8868 }
8869
8870 @Override
8871 public int getHighDischargeAmountSinceCharge() {
8872 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008873 int val = mHighDischargeAmountSinceCharge;
8874 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
8875 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
8876 }
8877 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008878 }
8879 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07008880
8881 @Override
8882 public int getDischargeAmount(int which) {
8883 int dischargeAmount = which == STATS_SINCE_CHARGED
8884 ? getHighDischargeAmountSinceCharge()
8885 : (getDischargeStartLevel() - getDischargeCurrentLevel());
8886 if (dischargeAmount < 0) {
8887 dischargeAmount = 0;
8888 }
8889 return dischargeAmount;
8890 }
8891
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008892 public int getDischargeAmountScreenOn() {
8893 synchronized(this) {
8894 int val = mDischargeAmountScreenOn;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008895 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008896 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
8897 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
8898 }
8899 return val;
8900 }
8901 }
8902
8903 public int getDischargeAmountScreenOnSinceCharge() {
8904 synchronized(this) {
8905 int val = mDischargeAmountScreenOnSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008906 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008907 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
8908 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
8909 }
8910 return val;
8911 }
8912 }
8913
8914 public int getDischargeAmountScreenOff() {
8915 synchronized(this) {
8916 int val = mDischargeAmountScreenOff;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008917 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008918 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
8919 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
8920 }
8921 return val;
8922 }
8923 }
8924
8925 public int getDischargeAmountScreenOffSinceCharge() {
8926 synchronized(this) {
8927 int val = mDischargeAmountScreenOffSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008928 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008929 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
8930 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
8931 }
8932 return val;
8933 }
8934 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008936 /**
8937 * Retrieve the statistics object for a particular uid, creating if needed.
8938 */
8939 public Uid getUidStatsLocked(int uid) {
8940 Uid u = mUidStats.get(uid);
8941 if (u == null) {
8942 u = new Uid(uid);
8943 mUidStats.put(uid, u);
8944 }
8945 return u;
8946 }
8947
8948 /**
8949 * Remove the statistics object for a particular uid.
8950 */
8951 public void removeUidStatsLocked(int uid) {
Adam Lesinskib83ffee2015-05-12 14:43:47 -07008952 mKernelUidCpuTimeReader.removeUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008953 mUidStats.remove(uid);
8954 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07008955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008956 /**
8957 * Retrieve the statistics object for a particular process, creating
8958 * if needed.
8959 */
8960 public Uid.Proc getProcessStatsLocked(int uid, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008961 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008962 Uid u = getUidStatsLocked(uid);
8963 return u.getProcessStatsLocked(name);
8964 }
8965
8966 /**
8967 * Retrieve the statistics object for a particular process, creating
8968 * if needed.
8969 */
8970 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008971 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008972 Uid u = getUidStatsLocked(uid);
8973 return u.getPackageStatsLocked(pkg);
8974 }
8975
8976 /**
8977 * Retrieve the statistics object for a particular service, creating
8978 * if needed.
8979 */
8980 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008981 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008982 Uid u = getUidStatsLocked(uid);
8983 return u.getServiceStatsLocked(pkg, name);
8984 }
8985
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008986 public void shutdownLocked() {
Dianne Hackborn29cd7f12015-01-08 10:37:05 -08008987 recordShutdownLocked(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008988 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008989 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008990 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008991
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008992 Parcel mPendingWrite = null;
8993 final ReentrantLock mWriteLock = new ReentrantLock();
8994
8995 public void writeAsyncLocked() {
8996 writeLocked(false);
8997 }
8998
8999 public void writeSyncLocked() {
9000 writeLocked(true);
9001 }
9002
9003 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009004 if (mFile == null) {
9005 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009006 return;
9007 }
9008
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009009 if (mShuttingDown) {
9010 return;
9011 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009012
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009013 Parcel out = Parcel.obtain();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009014 writeSummaryToParcel(out, true);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009015 mLastWriteTime = SystemClock.elapsedRealtime();
9016
9017 if (mPendingWrite != null) {
9018 mPendingWrite.recycle();
9019 }
9020 mPendingWrite = out;
9021
9022 if (sync) {
9023 commitPendingDataToDisk();
9024 } else {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009025 BackgroundThread.getHandler().post(new Runnable() {
9026 @Override public void run() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009027 commitPendingDataToDisk();
9028 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009029 });
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009030 }
9031 }
9032
9033 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07009034 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009035 synchronized (this) {
9036 next = mPendingWrite;
9037 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07009038 if (next == null) {
9039 return;
9040 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009041
9042 mWriteLock.lock();
9043 }
9044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009045 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009046 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009047 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009048 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07009049 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009050 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009051 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009052 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009053 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009054 mFile.rollback();
9055 } finally {
9056 next.recycle();
9057 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07009058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009059 }
9060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009061 public void readLocked() {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009062 if (mDailyFile != null) {
9063 readDailyStatsLocked();
9064 }
9065
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009066 if (mFile == null) {
9067 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009068 return;
9069 }
9070
9071 mUidStats.clear();
9072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009073 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009074 File file = mFile.chooseForRead();
9075 if (!file.exists()) {
9076 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009077 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009078 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009079
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009080 byte[] raw = BatteryStatsHelper.readFully(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009081 Parcel in = Parcel.obtain();
9082 in.unmarshall(raw, 0, raw.length);
9083 in.setDataPosition(0);
9084 stream.close();
9085
9086 readSummaryFromParcel(in);
Dianne Hackborn00e25212014-02-19 10:49:24 -08009087 } catch(Exception e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009088 Slog.e("BatteryStats", "Error reading battery statistics", e);
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009089 resetAllStatsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009090 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009091
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009092 mEndPlatformVersion = Build.ID;
9093
Dianne Hackborne5167ca2014-03-08 14:39:10 -08009094 if (mHistoryBuffer.dataPosition() > 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009095 mRecordingHistory = true;
Dianne Hackborn40c87252014-03-19 16:55:40 -07009096 final long elapsedRealtime = SystemClock.elapsedRealtime();
9097 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08009098 if (USE_OLD_HISTORY) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009099 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08009100 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009101 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
9102 startRecordingHistory(elapsedRealtime, uptime, false);
Dianne Hackborne8c88e62011-08-17 19:09:09 -07009103 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009104
9105 recordDailyStatsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009106 }
9107
9108 public int describeContents() {
9109 return 0;
9110 }
9111
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009112 void readHistory(Parcel in, boolean andOldHistory) throws ParcelFormatException {
Dianne Hackbornae384452011-06-28 12:33:48 -07009113 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009114
9115 mHistoryBuffer.setDataSize(0);
9116 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009117 mHistoryTagPool.clear();
9118 mNextHistoryTagIdx = 0;
9119 mNumHistoryTagChars = 0;
Dianne Hackborn099bc622014-01-22 13:39:16 -08009120
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009121 int numTags = in.readInt();
9122 for (int i=0; i<numTags; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08009123 int idx = in.readInt();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009124 String str = in.readString();
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009125 if (str == null) {
9126 throw new ParcelFormatException("null history tag string");
9127 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009128 int uid = in.readInt();
9129 HistoryTag tag = new HistoryTag();
9130 tag.string = str;
9131 tag.uid = uid;
9132 tag.poolIdx = idx;
9133 mHistoryTagPool.put(tag, idx);
9134 if (idx >= mNextHistoryTagIdx) {
9135 mNextHistoryTagIdx = idx+1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08009136 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009137 mNumHistoryTagChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08009138 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009139
9140 int bufSize = in.readInt();
9141 int curPos = in.dataPosition();
9142 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009143 throw new ParcelFormatException("File corrupt: history data buffer too large " +
9144 bufSize);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009145 } else if ((bufSize&~3) != bufSize) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009146 throw new ParcelFormatException("File corrupt: history data buffer not aligned " +
9147 bufSize);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009148 } else {
9149 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
9150 + " bytes at " + curPos);
9151 mHistoryBuffer.appendFrom(in, curPos, bufSize);
9152 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009153 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009154
Dianne Hackbornae384452011-06-28 12:33:48 -07009155 if (andOldHistory) {
9156 readOldHistory(in);
9157 }
9158
9159 if (DEBUG_HISTORY) {
9160 StringBuilder sb = new StringBuilder(128);
9161 sb.append("****************** OLD mHistoryBaseTime: ");
9162 TimeUtils.formatDuration(mHistoryBaseTime, sb);
9163 Slog.i(TAG, sb.toString());
9164 }
9165 mHistoryBaseTime = historyBaseTime;
9166 if (DEBUG_HISTORY) {
9167 StringBuilder sb = new StringBuilder(128);
9168 sb.append("****************** NEW mHistoryBaseTime: ");
9169 TimeUtils.formatDuration(mHistoryBaseTime, sb);
9170 Slog.i(TAG, sb.toString());
9171 }
9172
9173 // We are just arbitrarily going to insert 1 minute from the sample of
9174 // the last run until samples in this run.
9175 if (mHistoryBaseTime > 0) {
9176 long oldnow = SystemClock.elapsedRealtime();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009177 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1;
Dianne Hackbornae384452011-06-28 12:33:48 -07009178 if (DEBUG_HISTORY) {
9179 StringBuilder sb = new StringBuilder(128);
9180 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
9181 TimeUtils.formatDuration(mHistoryBaseTime, sb);
9182 Slog.i(TAG, sb.toString());
9183 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07009184 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009185 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009186
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009187 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07009188 if (!USE_OLD_HISTORY) {
9189 return;
9190 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009191 mHistory = mHistoryEnd = mHistoryCache = null;
9192 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07009193 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009194 HistoryItem rec = new HistoryItem(time, in);
9195 addHistoryRecordLocked(rec);
9196 }
9197 }
9198
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009199 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) {
Dianne Hackbornae384452011-06-28 12:33:48 -07009200 if (DEBUG_HISTORY) {
9201 StringBuilder sb = new StringBuilder(128);
9202 sb.append("****************** WRITING mHistoryBaseTime: ");
9203 TimeUtils.formatDuration(mHistoryBaseTime, sb);
Dianne Hackborn40c87252014-03-19 16:55:40 -07009204 sb.append(" mLastHistoryElapsedRealtime: ");
9205 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
Dianne Hackbornae384452011-06-28 12:33:48 -07009206 Slog.i(TAG, sb.toString());
9207 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07009208 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009209 if (!inclData) {
9210 out.writeInt(0);
9211 out.writeInt(0);
9212 return;
9213 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009214 out.writeInt(mHistoryTagPool.size());
9215 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
9216 HistoryTag tag = ent.getKey();
Dianne Hackborn099bc622014-01-22 13:39:16 -08009217 out.writeInt(ent.getValue());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009218 out.writeString(tag.string);
9219 out.writeInt(tag.uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08009220 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009221 out.writeInt(mHistoryBuffer.dataSize());
9222 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
9223 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
9224 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07009225
9226 if (andOldHistory) {
9227 writeOldHistory(out);
9228 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009229 }
9230
9231 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07009232 if (!USE_OLD_HISTORY) {
9233 return;
9234 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009235 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009236 while (rec != null) {
9237 if (rec.time >= 0) rec.writeToParcel(out, 0);
9238 rec = rec.next;
9239 }
9240 out.writeLong(-1);
9241 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009242
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009243 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009244 final int version = in.readInt();
9245 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009246 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009247 + ", expected " + VERSION + "; erasing old stats");
9248 return;
9249 }
9250
Dianne Hackbornae384452011-06-28 12:33:48 -07009251 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009253 mStartCount = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009254 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009255 mRealtime = in.readLong();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009256 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009257 mStartPlatformVersion = in.readString();
9258 mEndPlatformVersion = in.readString();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009259 mOnBatteryTimeBase.readSummaryFromParcel(in);
9260 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009261 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009262 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07009263 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009264 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009265 mLowDischargeAmountSinceCharge = in.readInt();
9266 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009267 mDischargeAmountScreenOnSinceCharge = in.readInt();
9268 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009269 mDischargeStepTracker.readFromParcel(in);
9270 mChargeStepTracker.readFromParcel(in);
9271 mDailyDischargeStepTracker.readFromParcel(in);
9272 mDailyChargeStepTracker.readFromParcel(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009273 int NPKG = in.readInt();
9274 if (NPKG > 0) {
9275 mDailyPackageChanges = new ArrayList<>(NPKG);
9276 while (NPKG > 0) {
9277 NPKG--;
9278 PackageChange pc = new PackageChange();
9279 pc.mPackageName = in.readString();
9280 pc.mUpdate = in.readInt() != 0;
9281 pc.mVersionCode = in.readInt();
9282 mDailyPackageChanges.add(pc);
9283 }
9284 } else {
9285 mDailyPackageChanges = null;
9286 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009287 mDailyStartTime = in.readLong();
9288 mNextMinDailyDeadline = in.readLong();
9289 mNextMaxDailyDeadline = in.readLong();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009291 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009292
Jeff Browne95c3cd2014-05-02 16:59:26 -07009293 mScreenState = Display.STATE_UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009294 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009295 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
9296 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
9297 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009298 mInteractive = false;
9299 mInteractiveTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009300 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009301 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07009302 mLongestLightIdleTime = in.readLong();
9303 mLongestFullIdleTime = in.readLong();
9304 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in);
9305 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in);
9306 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009307 mDeviceIdlingTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009308 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08009309 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07009310 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
9311 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07009312 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009313 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
9314 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
9315 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009316 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009317 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
9318 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009319 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009320 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009321 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08009322 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009323 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009324 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
9325 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07009326 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
The Android Open Source Project10592532009-03-18 17:39:46 -07009327 mWifiOn = false;
9328 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009329 mGlobalWifiRunning = false;
9330 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009331 for (int i=0; i<NUM_WIFI_STATES; i++) {
9332 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
9333 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009334 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9335 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in);
9336 }
9337 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9338 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
9339 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009340 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9341 mBluetoothActivityCounters[i].readSummaryFromParcelLocked(in);
9342 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009343 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9344 mWifiActivityCounters[i].readSummaryFromParcelLocked(in);
9345 }
9346
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009347 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07009348 mFlashlightOnNesting = 0;
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009349 mFlashlightOnTimer.readSummaryFromParcelLocked(in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07009350 mCameraOnNesting = 0;
9351 mCameraOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009352
Evan Millarc64edde2009-04-18 12:26:32 -07009353 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009354 if (NKW > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009355 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009356 }
Evan Millarc64edde2009-04-18 12:26:32 -07009357 for (int ikw = 0; ikw < NKW; ikw++) {
9358 if (in.readInt() != 0) {
9359 String kwltName = in.readString();
9360 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
9361 }
9362 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07009363
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009364 int NWR = in.readInt();
9365 if (NWR > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009366 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009367 }
9368 for (int iwr = 0; iwr < NWR; iwr++) {
9369 if (in.readInt() != 0) {
9370 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009371 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009372 }
9373 }
9374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009375 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009376 if (NU > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009377 throw new ParcelFormatException("File corrupt: too many uids " + NU);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009379 for (int iu = 0; iu < NU; iu++) {
9380 int uid = in.readInt();
9381 Uid u = new Uid(uid);
9382 mUidStats.put(uid, u);
9383
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009384 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009385 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009386 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009387 }
The Android Open Source Project10592532009-03-18 17:39:46 -07009388 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009389 if (in.readInt() != 0) {
9390 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
9391 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07009392 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009393 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07009394 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009395 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07009396 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
9397 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
9398 if (in.readInt() != 0) {
9399 u.makeWifiBatchedScanBin(i, null);
9400 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
9401 }
9402 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07009403 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009404 if (in.readInt() != 0) {
9405 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
9406 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009407 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009408 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009409 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009410 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009411 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
9412 }
9413 if (in.readInt() != 0) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -07009414 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
9415 }
9416 if (in.readInt() != 0) {
9417 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
9418 }
9419 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009420 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
9421 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08009422 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
Dianne Hackborn61659e52014-07-09 16:13:01 -07009423 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
9424 if (in.readInt() != 0) {
9425 u.makeProcessState(i, null);
9426 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in);
9427 }
9428 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009429 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009430 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009431 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07009432
Dianne Hackborn617f8772009-03-31 15:04:46 -07009433 if (in.readInt() != 0) {
9434 if (u.mUserActivityCounters == null) {
9435 u.initUserActivityLocked();
9436 }
9437 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
9438 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
9439 }
9440 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009441
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009442 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009443 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009444 u.initNetworkActivityLocked();
9445 }
9446 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009447 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
9448 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009449 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009450 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
9451 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009452 }
9453
Adam Lesinski06af1fa2015-05-05 17:35:35 -07009454 u.mUserCpuTime.readSummaryFromParcelLocked(in);
9455 u.mSystemCpuTime.readSummaryFromParcelLocked(in);
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07009456 u.mCpuPower.readSummaryFromParcelLocked(in);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07009457
Adam Lesinski6832f392015-09-05 18:05:40 -07009458 if (in.readInt() != 0) {
9459 final int numClusters = in.readInt();
9460 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) {
9461 throw new ParcelFormatException("Incompatible cpu cluster arrangement");
Adam Lesinski06af1fa2015-05-05 17:35:35 -07009462 }
Adam Lesinski6832f392015-09-05 18:05:40 -07009463
9464 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][];
9465 for (int cluster = 0; cluster < numClusters; cluster++) {
Adam Lesinski6832f392015-09-05 18:05:40 -07009466 if (in.readInt() != 0) {
Adam Lesinskia57a5402015-09-28 10:21:33 -07009467 final int NSB = in.readInt();
9468 if (mPowerProfile != null &&
9469 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) {
9470 throw new ParcelFormatException("File corrupt: too many speed bins " +
9471 NSB);
9472 }
9473
Adam Lesinski6832f392015-09-05 18:05:40 -07009474 u.mCpuClusterSpeed[cluster] = new LongSamplingCounter[NSB];
9475 for (int speed = 0; speed < NSB; speed++) {
9476 if (in.readInt() != 0) {
9477 u.mCpuClusterSpeed[cluster][speed] = new LongSamplingCounter(
9478 mOnBatteryTimeBase);
9479 u.mCpuClusterSpeed[cluster][speed].readSummaryFromParcelLocked(in);
9480 }
9481 }
Adam Lesinskia57a5402015-09-28 10:21:33 -07009482 } else {
9483 u.mCpuClusterSpeed[cluster] = null;
Adam Lesinski6832f392015-09-05 18:05:40 -07009484 }
9485 }
9486 } else {
9487 u.mCpuClusterSpeed = null;
Adam Lesinski06af1fa2015-05-05 17:35:35 -07009488 }
9489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009490 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009491 if (NW > 100) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009492 throw new ParcelFormatException("File corrupt: too many wake locks " + NW);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009493 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 for (int iw = 0; iw < NW; iw++) {
9495 String wlName = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07009496 u.readWakeSummaryFromParcelLocked(wlName, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009497 }
9498
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009499 int NS = in.readInt();
9500 if (NS > 100) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009501 throw new ParcelFormatException("File corrupt: too many syncs " + NS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009502 }
9503 for (int is = 0; is < NS; is++) {
9504 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07009505 u.readSyncSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009506 }
9507
9508 int NJ = in.readInt();
9509 if (NJ > 100) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009510 throw new ParcelFormatException("File corrupt: too many job timers " + NJ);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009511 }
9512 for (int ij = 0; ij < NJ; ij++) {
9513 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07009514 u.readJobSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009515 }
9516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009517 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009518 if (NP > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009519 throw new ParcelFormatException("File corrupt: too many sensors " + NP);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009521 for (int is = 0; is < NP; is++) {
9522 int seNumber = in.readInt();
9523 if (in.readInt() != 0) {
9524 u.getSensorTimerLocked(seNumber, true)
9525 .readSummaryFromParcelLocked(in);
9526 }
9527 }
9528
9529 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009530 if (NP > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009531 throw new ParcelFormatException("File corrupt: too many processes " + NP);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009533 for (int ip = 0; ip < NP; ip++) {
9534 String procName = in.readString();
9535 Uid.Proc p = u.getProcessStatsLocked(procName);
9536 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009537 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009538 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009539 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009540 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt();
9541 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt();
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009542 p.readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009543 }
9544
9545 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009546 if (NP > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009547 throw new ParcelFormatException("File corrupt: too many packages " + NP);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009549 for (int ip = 0; ip < NP; ip++) {
9550 String pkgName = in.readString();
9551 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009552 final int NWA = in.readInt();
9553 if (NWA > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009554 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009555 }
9556 p.mWakeupAlarms.clear();
9557 for (int iwa=0; iwa<NWA; iwa++) {
9558 String tag = in.readString();
9559 Counter c = new Counter(mOnBatteryTimeBase);
9560 c.readSummaryFromParcelLocked(in);
9561 p.mWakeupAlarms.put(tag, c);
9562 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009563 NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009564 if (NS > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07009565 throw new ParcelFormatException("File corrupt: too many services " + NS);
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009567 for (int is = 0; is < NS; is++) {
9568 String servName = in.readString();
9569 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
9570 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009571 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009572 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009573 }
9574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009575 }
9576 }
9577
9578 /**
9579 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
9580 * disk. This format does not allow a lossless round-trip.
9581 *
9582 * @param out the Parcel to be written to.
9583 */
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009584 public void writeSummaryToParcel(Parcel out, boolean inclHistory) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009585 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009586
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009587 // Pull the clock time. This may update the time and make a new history entry
9588 // if we had originally pulled a time before the RTC was set.
9589 long startClockTime = getStartClockTime();
9590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009591 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
9592 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009593
9594 out.writeInt(VERSION);
9595
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009596 writeHistory(out, inclHistory, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009598 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009599 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009600 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009601 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009602 out.writeString(mStartPlatformVersion);
9603 out.writeString(mEndPlatformVersion);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009604 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
9605 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009606 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009607 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07009608 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009609 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08009610 out.writeInt(getLowDischargeAmountSinceCharge());
9611 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009612 out.writeInt(getDischargeAmountScreenOnSinceCharge());
9613 out.writeInt(getDischargeAmountScreenOffSinceCharge());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009614 mDischargeStepTracker.writeToParcel(out);
9615 mChargeStepTracker.writeToParcel(out);
9616 mDailyDischargeStepTracker.writeToParcel(out);
9617 mDailyChargeStepTracker.writeToParcel(out);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009618 if (mDailyPackageChanges != null) {
9619 final int NPKG = mDailyPackageChanges.size();
9620 out.writeInt(NPKG);
9621 for (int i=0; i<NPKG; i++) {
9622 PackageChange pc = mDailyPackageChanges.get(i);
9623 out.writeString(pc.mPackageName);
9624 out.writeInt(pc.mUpdate ? 1 : 0);
9625 out.writeInt(pc.mVersionCode);
9626 }
9627 } else {
9628 out.writeInt(0);
9629 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009630 out.writeLong(mDailyStartTime);
9631 out.writeLong(mNextMinDailyDeadline);
9632 out.writeLong(mNextMaxDailyDeadline);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009633
9634 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009635 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009636 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009637 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009638 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009639 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07009640 out.writeLong(mLongestLightIdleTime);
9641 out.writeLong(mLongestFullIdleTime);
9642 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9643 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9644 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009645 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009646 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Wink Saville52840902011-02-18 12:40:47 -08009647 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009648 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009649 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009650 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009651 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009652 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009653 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009654 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009655 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
9656 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009657 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009658 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9659 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009660 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009661 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
9662 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009663 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9664 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009665 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009666 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009667 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009668 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9669 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9670 }
9671 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9672 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9673 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009674 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9675 mBluetoothActivityCounters[i].writeSummaryFromParcelLocked(out);
9676 }
9677 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9678 mWifiActivityCounters[i].writeSummaryFromParcelLocked(out);
9679 }
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009680 out.writeInt(mNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009681 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07009682 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009683
Evan Millarc64edde2009-04-18 12:26:32 -07009684 out.writeInt(mKernelWakelockStats.size());
9685 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
9686 Timer kwlt = ent.getValue();
9687 if (kwlt != null) {
9688 out.writeInt(1);
9689 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009690 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9691 } else {
9692 out.writeInt(0);
9693 }
9694 }
9695
9696 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009697 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
9698 SamplingTimer timer = ent.getValue();
9699 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009700 out.writeInt(1);
9701 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009702 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Evan Millarc64edde2009-04-18 12:26:32 -07009703 } else {
9704 out.writeInt(0);
9705 }
9706 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009708 final int NU = mUidStats.size();
9709 out.writeInt(NU);
9710 for (int iu = 0; iu < NU; iu++) {
9711 out.writeInt(mUidStats.keyAt(iu));
9712 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009713
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009714 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009715 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009716 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009717 } else {
9718 out.writeInt(0);
9719 }
9720 if (u.mFullWifiLockTimer != null) {
9721 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009722 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009723 } else {
9724 out.writeInt(0);
9725 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07009726 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009727 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009728 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009729 } else {
9730 out.writeInt(0);
9731 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07009732 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
9733 if (u.mWifiBatchedScanTimer[i] != null) {
9734 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009735 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Robert Greenwalta029ea12013-09-25 16:38:12 -07009736 } else {
9737 out.writeInt(0);
9738 }
9739 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009740 if (u.mWifiMulticastTimer != null) {
9741 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009742 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009743 } else {
9744 out.writeInt(0);
9745 }
9746 if (u.mAudioTurnedOnTimer != null) {
9747 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009748 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009749 } else {
9750 out.writeInt(0);
9751 }
9752 if (u.mVideoTurnedOnTimer != null) {
9753 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009754 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009755 } else {
9756 out.writeInt(0);
9757 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07009758 if (u.mFlashlightTurnedOnTimer != null) {
9759 out.writeInt(1);
9760 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9761 } else {
9762 out.writeInt(0);
9763 }
9764 if (u.mCameraTurnedOnTimer != null) {
9765 out.writeInt(1);
9766 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9767 } else {
9768 out.writeInt(0);
9769 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009770 if (u.mForegroundActivityTimer != null) {
9771 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009772 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009773 } else {
9774 out.writeInt(0);
9775 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07009776 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
9777 if (u.mProcessStateTimer[i] != null) {
9778 out.writeInt(1);
9779 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9780 } else {
9781 out.writeInt(0);
9782 }
9783 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009784 if (u.mVibratorOnTimer != null) {
9785 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009786 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009787 } else {
9788 out.writeInt(0);
9789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009790
Dianne Hackborn617f8772009-03-31 15:04:46 -07009791 if (u.mUserActivityCounters == null) {
9792 out.writeInt(0);
9793 } else {
9794 out.writeInt(1);
9795 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
9796 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
9797 }
9798 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009799
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009800 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009801 out.writeInt(0);
9802 } else {
9803 out.writeInt(1);
9804 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009805 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
9806 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009807 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009808 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
9809 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009810 }
9811
Adam Lesinski06af1fa2015-05-05 17:35:35 -07009812 u.mUserCpuTime.writeSummaryFromParcelLocked(out);
9813 u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
Adam Lesinskia7a4ccc2015-06-26 17:43:04 -07009814 u.mCpuPower.writeSummaryFromParcelLocked(out);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07009815
Adam Lesinski6832f392015-09-05 18:05:40 -07009816 if (u.mCpuClusterSpeed != null) {
9817 out.writeInt(1);
9818 out.writeInt(u.mCpuClusterSpeed.length);
9819 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeed) {
9820 if (cpuSpeeds != null) {
9821 out.writeInt(1);
9822 out.writeInt(cpuSpeeds.length);
9823 for (LongSamplingCounter c : cpuSpeeds) {
9824 if (c != null) {
9825 out.writeInt(1);
9826 c.writeSummaryFromParcelLocked(out);
9827 } else {
9828 out.writeInt(0);
9829 }
9830 }
9831 } else {
9832 out.writeInt(0);
9833 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07009834 }
Adam Lesinski6832f392015-09-05 18:05:40 -07009835 } else {
9836 out.writeInt(0);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07009837 }
9838
Dianne Hackbornd953c532014-08-16 18:17:38 -07009839 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
9840 int NW = wakeStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009841 out.writeInt(NW);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009842 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009843 out.writeString(wakeStats.keyAt(iw));
9844 Uid.Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009845 if (wl.mTimerFull != null) {
9846 out.writeInt(1);
9847 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9848 } else {
9849 out.writeInt(0);
9850 }
9851 if (wl.mTimerPartial != null) {
9852 out.writeInt(1);
9853 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9854 } else {
9855 out.writeInt(0);
9856 }
9857 if (wl.mTimerWindow != null) {
9858 out.writeInt(1);
9859 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9860 } else {
9861 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009862 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07009863 if (wl.mTimerDraw != null) {
Adam Lesinski9425fe22015-06-19 12:02:13 -07009864 out.writeInt(1);
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07009865 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Adam Lesinski9425fe22015-06-19 12:02:13 -07009866 } else {
9867 out.writeInt(0);
9868 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009869 }
9870
Dianne Hackbornd953c532014-08-16 18:17:38 -07009871 final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap();
9872 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009873 out.writeInt(NS);
9874 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009875 out.writeString(syncStats.keyAt(is));
9876 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009877 }
9878
Dianne Hackbornd953c532014-08-16 18:17:38 -07009879 final ArrayMap<String, StopwatchTimer> jobStats = u.mJobStats.getMap();
9880 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009881 out.writeInt(NJ);
9882 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009883 out.writeString(jobStats.keyAt(ij));
9884 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009885 }
9886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009887 int NSE = u.mSensorStats.size();
9888 out.writeInt(NSE);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009889 for (int ise=0; ise<NSE; ise++) {
9890 out.writeInt(u.mSensorStats.keyAt(ise));
9891 Uid.Sensor se = u.mSensorStats.valueAt(ise);
9892 if (se.mTimer != null) {
9893 out.writeInt(1);
9894 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9895 } else {
9896 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009897 }
9898 }
9899
9900 int NP = u.mProcessStats.size();
9901 out.writeInt(NP);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009902 for (int ip=0; ip<NP; ip++) {
9903 out.writeString(u.mProcessStats.keyAt(ip));
9904 Uid.Proc ps = u.mProcessStats.valueAt(ip);
9905 out.writeLong(ps.mUserTime);
9906 out.writeLong(ps.mSystemTime);
9907 out.writeLong(ps.mForegroundTime);
9908 out.writeInt(ps.mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009909 out.writeInt(ps.mNumCrashes);
9910 out.writeInt(ps.mNumAnrs);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009911 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009912 }
9913
9914 NP = u.mPackageStats.size();
9915 out.writeInt(NP);
9916 if (NP > 0) {
9917 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
9918 : u.mPackageStats.entrySet()) {
9919 out.writeString(ent.getKey());
9920 Uid.Pkg ps = ent.getValue();
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009921 final int NWA = ps.mWakeupAlarms.size();
9922 out.writeInt(NWA);
9923 for (int iwa=0; iwa<NWA; iwa++) {
9924 out.writeString(ps.mWakeupAlarms.keyAt(iwa));
9925 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out);
9926 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009927 NS = ps.mServiceStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009928 out.writeInt(NS);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009929 for (int is=0; is<NS; is++) {
9930 out.writeString(ps.mServiceStats.keyAt(is));
9931 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
9932 long time = ss.getStartTimeToNowLocked(
9933 mOnBatteryTimeBase.getUptime(NOW_SYS));
9934 out.writeLong(time);
9935 out.writeInt(ss.mStarts);
9936 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009937 }
9938 }
9939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009940 }
9941 }
9942
9943 public void readFromParcel(Parcel in) {
9944 readFromParcelLocked(in);
9945 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009947 void readFromParcelLocked(Parcel in) {
9948 int magic = in.readInt();
9949 if (magic != MAGIC) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009950 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009951 }
9952
Dianne Hackbornae384452011-06-28 12:33:48 -07009953 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009955 mStartCount = in.readInt();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009956 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009957 mStartPlatformVersion = in.readString();
9958 mEndPlatformVersion = in.readString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009959 mUptime = in.readLong();
9960 mUptimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009961 mRealtime = in.readLong();
9962 mRealtimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009963 mOnBattery = in.readInt() != 0;
9964 mOnBatteryInternal = false; // we are no longer really running.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009965 mOnBatteryTimeBase.readFromParcel(in);
9966 mOnBatteryScreenOffTimeBase.readFromParcel(in);
9967
Jeff Browne95c3cd2014-05-02 16:59:26 -07009968 mScreenState = Display.STATE_UNKNOWN;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009969 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase, in);
9970 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
9971 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase,
9972 in);
9973 }
Dianne Hackborn29325132014-05-21 15:01:03 -07009974 mInteractive = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009975 mInteractiveTimer = new StopwatchTimer(null, -10, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009976 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009977 mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07009978 mLongestLightIdleTime = in.readLong();
9979 mLongestFullIdleTime = in.readLong();
9980 mDeviceIdleModeLightTimer = new StopwatchTimer(null, -14, null, mOnBatteryTimeBase, in);
9981 mDeviceIdleModeFullTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase, in);
9982 mDeviceLightIdlingTimer = new StopwatchTimer(null, -15, null, mOnBatteryTimeBase, in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009983 mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase, in);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009984 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009985 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
9986 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
9987 null, mOnBatteryTimeBase, in);
9988 }
9989 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase, in);
9990 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
9991 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
9992 null, mOnBatteryTimeBase, in);
9993 }
9994 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
9995 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9996 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9997 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009998 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009999 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in);
10000 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase,
10001 in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010002 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010003 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
10004 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn0c820db2015-04-14 17:47:34 -070010005 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010006 mWifiOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070010007 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010008 mGlobalWifiRunning = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070010009 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010010 for (int i=0; i<NUM_WIFI_STATES; i++) {
10011 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
10012 null, mOnBatteryTimeBase, in);
10013 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070010014 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
10015 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i,
10016 null, mOnBatteryTimeBase, in);
10017 }
10018 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
10019 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i,
10020 null, mOnBatteryTimeBase, in);
10021 }
Adam Lesinski33dac552015-03-09 15:24:48 -070010022 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
10023 mBluetoothActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
10024 }
Adam Lesinski33dac552015-03-09 15:24:48 -070010025 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
10026 mWifiActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
10027 }
10028
Adam Lesinski17390762015-04-10 13:17:47 -070010029 mHasWifiEnergyReporting = in.readInt() != 0;
10030 mHasBluetoothEnergyReporting = in.readInt() != 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -080010031 mNumConnectivityChange = in.readInt();
10032 mLoadedNumConnectivityChange = in.readInt();
10033 mUnpluggedNumConnectivityChange = in.readInt();
Dianne Hackborn10eaa852014-07-22 22:54:55 -070010034 mAudioOnNesting = 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070010035 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
Dianne Hackborn10eaa852014-07-22 22:54:55 -070010036 mVideoOnNesting = 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070010037 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070010038 mFlashlightOnNesting = 0;
Dianne Hackbornabc7c492014-06-30 16:57:46 -070010039 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070010040 mCameraOnNesting = 0;
10041 mCameraOnTimer = new StopwatchTimer(null, -13, null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070010042 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070010043 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -070010044 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070010045 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070010046 mLowDischargeAmountSinceCharge = in.readInt();
10047 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080010048 mDischargeAmountScreenOn = in.readInt();
10049 mDischargeAmountScreenOnSinceCharge = in.readInt();
10050 mDischargeAmountScreenOff = in.readInt();
10051 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080010052 mDischargeStepTracker.readFromParcel(in);
10053 mChargeStepTracker.readFromParcel(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010054 mLastWriteTime = in.readLong();
10055
Evan Millarc64edde2009-04-18 12:26:32 -070010056 mKernelWakelockStats.clear();
10057 int NKW = in.readInt();
10058 for (int ikw = 0; ikw < NKW; ikw++) {
10059 if (in.readInt() != 0) {
10060 String wakelockName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070010061 SamplingTimer kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -070010062 mKernelWakelockStats.put(wakelockName, kwlt);
10063 }
10064 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070010065
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010066 mWakeupReasonStats.clear();
10067 int NWR = in.readInt();
10068 for (int iwr = 0; iwr < NWR; iwr++) {
10069 if (in.readInt() != 0) {
10070 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070010071 SamplingTimer timer = new SamplingTimer(mOnBatteryTimeBase, in);
10072 mWakeupReasonStats.put(reasonName, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010073 }
10074 }
10075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010076 mPartialTimers.clear();
10077 mFullTimers.clear();
10078 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070010079 mWifiRunningTimers.clear();
10080 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -070010081 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -070010082 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070010083 mWifiMulticastTimers.clear();
Dianne Hackborn10eaa852014-07-22 22:54:55 -070010084 mAudioTurnedOnTimers.clear();
10085 mVideoTurnedOnTimers.clear();
Ruben Brunk6d2c3632015-05-26 17:32:16 -070010086 mFlashlightTurnedOnTimers.clear();
10087 mCameraTurnedOnTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010088
10089 int numUids = in.readInt();
10090 mUidStats.clear();
10091 for (int i = 0; i < numUids; i++) {
10092 int uid = in.readInt();
10093 Uid u = new Uid(uid);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010094 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010095 mUidStats.append(uid, u);
10096 }
10097 }
10098
10099 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070010100 writeToParcelLocked(out, true, flags);
10101 }
10102
10103 public void writeToParcelWithoutUids(Parcel out, int flags) {
10104 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010105 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070010106
10107 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070010108 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070010109 // Need to update with current kernel wake lock counts.
Dianne Hackborna7c837f2014-01-15 16:20:44 -080010110 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070010111
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070010112 // Pull the clock time. This may update the time and make a new history entry
10113 // if we had originally pulled a time before the RTC was set.
10114 long startClockTime = getStartClockTime();
10115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010116 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
10117 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010118 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
10119 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070010120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010121 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070010122
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070010123 writeHistory(out, true, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070010124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010125 out.writeInt(mStartCount);
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070010126 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -070010127 out.writeString(mStartPlatformVersion);
10128 out.writeString(mEndPlatformVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010129 out.writeLong(mUptime);
10130 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010131 out.writeLong(mRealtime);
10132 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010133 out.writeInt(mOnBattery ? 1 : 0);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010134 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
10135 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
10136
10137 mScreenOnTimer.writeToParcel(out, uSecRealtime);
10138 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
10139 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
10140 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070010141 mInteractiveTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070010142 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn08c47a52015-10-15 12:38:14 -070010143 out.writeLong(mLongestLightIdleTime);
10144 out.writeLong(mLongestFullIdleTime);
10145 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime);
10146 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime);
10147 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070010148 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010149 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
10150 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
10151 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
10152 }
10153 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
10154 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
10155 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
10156 }
10157 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
10158 mNetworkByteActivityCounters[i].writeToParcel(out);
10159 mNetworkPacketActivityCounters[i].writeToParcel(out);
10160 }
10161 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
10162 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010163 mMobileRadioActiveAdjustedTime.writeToParcel(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010164 mMobileRadioActiveUnknownTime.writeToParcel(out);
10165 mMobileRadioActiveUnknownCount.writeToParcel(out);
10166 mWifiOnTimer.writeToParcel(out, uSecRealtime);
10167 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
10168 for (int i=0; i<NUM_WIFI_STATES; i++) {
10169 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
10170 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070010171 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
10172 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime);
10173 }
10174 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
10175 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
10176 }
Adam Lesinski33dac552015-03-09 15:24:48 -070010177 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
10178 mBluetoothActivityCounters[i].writeToParcel(out);
10179 }
10180 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
10181 mWifiActivityCounters[i].writeToParcel(out);
10182 }
Adam Lesinski17390762015-04-10 13:17:47 -070010183 out.writeInt(mHasWifiEnergyReporting ? 1 : 0);
10184 out.writeInt(mHasBluetoothEnergyReporting ? 1 : 0);
Dianne Hackborn1e01d162014-12-04 17:46:42 -080010185 out.writeInt(mNumConnectivityChange);
10186 out.writeInt(mLoadedNumConnectivityChange);
10187 out.writeInt(mUnpluggedNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -070010188 mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070010189 mCameraOnTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070010190 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070010191 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -070010192 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070010193 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070010194 out.writeInt(mLowDischargeAmountSinceCharge);
10195 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080010196 out.writeInt(mDischargeAmountScreenOn);
10197 out.writeInt(mDischargeAmountScreenOnSinceCharge);
10198 out.writeInt(mDischargeAmountScreenOff);
10199 out.writeInt(mDischargeAmountScreenOffSinceCharge);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080010200 mDischargeStepTracker.writeToParcel(out);
10201 mChargeStepTracker.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010202 out.writeLong(mLastWriteTime);
10203
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070010204 if (inclUids) {
10205 out.writeInt(mKernelWakelockStats.size());
10206 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
10207 SamplingTimer kwlt = ent.getValue();
10208 if (kwlt != null) {
10209 out.writeInt(1);
10210 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010211 kwlt.writeToParcel(out, uSecRealtime);
10212 } else {
10213 out.writeInt(0);
10214 }
10215 }
10216 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070010217 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
10218 SamplingTimer timer = ent.getValue();
10219 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010220 out.writeInt(1);
10221 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070010222 timer.writeToParcel(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070010223 } else {
10224 out.writeInt(0);
10225 }
Evan Millarc64edde2009-04-18 12:26:32 -070010226 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070010227 } else {
10228 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -070010229 }
Amith Yamasanie43530a2009-08-21 13:11:37 -070010230
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070010231 if (inclUids) {
10232 int size = mUidStats.size();
10233 out.writeInt(size);
10234 for (int i = 0; i < size; i++) {
10235 out.writeInt(mUidStats.keyAt(i));
10236 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010237
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010238 uid.writeToParcelLocked(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070010239 }
10240 } else {
10241 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010242 }
10243 }
10244
10245 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
10246 new Parcelable.Creator<BatteryStatsImpl>() {
10247 public BatteryStatsImpl createFromParcel(Parcel in) {
10248 return new BatteryStatsImpl(in);
10249 }
10250
10251 public BatteryStatsImpl[] newArray(int size) {
10252 return new BatteryStatsImpl[size];
10253 }
10254 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070010255
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070010256 public void prepareForDumpLocked() {
10257 // Need to retrieve current kernel wake lock stats before printing.
Dianne Hackborna7c837f2014-01-15 16:20:44 -080010258 pullPendingStateUpdatesLocked();
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070010259
10260 // Pull the clock time. This may update the time and make a new history entry
10261 // if we had originally pulled a time before the RTC was set.
10262 getStartClockTime();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070010263 }
10264
Dianne Hackbornc51cf032014-03-02 19:08:15 -080010265 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010266 if (DEBUG) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010267 pw.println("mOnBatteryTimeBase:");
10268 mOnBatteryTimeBase.dump(pw, " ");
10269 pw.println("mOnBatteryScreenOffTimeBase:");
10270 mOnBatteryScreenOffTimeBase.dump(pw, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010271 Printer pr = new PrintWriterPrinter(pw);
10272 pr.println("*** Screen timer:");
10273 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -070010274 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010275 pr.println("*** Screen brightness #" + i + ":");
10276 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -070010277 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070010278 pr.println("*** Interactive timer:");
10279 mInteractiveTimer.logState(pr, " ");
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070010280 pr.println("*** Power save mode timer:");
10281 mPowerSaveModeEnabledTimer.logState(pr, " ");
Dianne Hackborn08c47a52015-10-15 12:38:14 -070010282 pr.println("*** Device idle mode light timer:");
10283 mDeviceIdleModeLightTimer.logState(pr, " ");
10284 pr.println("*** Device idle mode full timer:");
10285 mDeviceIdleModeFullTimer.logState(pr, " ");
10286 pr.println("*** Device light idling timer:");
10287 mDeviceLightIdlingTimer.logState(pr, " ");
Dianne Hackborn88e98df2015-03-23 13:29:14 -070010288 pr.println("*** Device idling timer:");
10289 mDeviceIdlingTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010290 pr.println("*** Phone timer:");
10291 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -080010292 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3251b902014-06-20 14:40:53 -070010293 pr.println("*** Phone signal strength #" + i + ":");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010294 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -070010295 }
Amith Yamasanif37447b2009-10-08 18:28:01 -070010296 pr.println("*** Signal scanning :");
10297 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -070010298 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010299 pr.println("*** Data connection type #" + i + ":");
10300 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -070010301 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070010302 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState);
Dianne Hackborne13c4c02014-02-11 17:18:35 -080010303 pr.println("*** Mobile network active timer:");
10304 mMobileRadioActiveTimer.logState(pr, " ");
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010305 pr.println("*** Mobile network active adjusted timer:");
10306 mMobileRadioActiveAdjustedTime.logState(pr, " ");
Dianne Hackborn0c820db2015-04-14 17:47:34 -070010307 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010308 pr.println("*** Wifi timer:");
10309 mWifiOnTimer.logState(pr, " ");
10310 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070010311 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -080010312 for (int i=0; i<NUM_WIFI_STATES; i++) {
10313 pr.println("*** Wifi state #" + i + ":");
10314 mWifiStateTimer[i].logState(pr, " ");
10315 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070010316 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
10317 pr.println("*** Wifi suppl state #" + i + ":");
10318 mWifiSupplStateTimer[i].logState(pr, " ");
10319 }
10320 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
10321 pr.println("*** Wifi signal strength #" + i + ":");
10322 mWifiSignalStrengthsTimer[i].logState(pr, " ");
10323 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -070010324 pr.println("*** Flashlight timer:");
10325 mFlashlightOnTimer.logState(pr, " ");
Ruben Brunk6d2c3632015-05-26 17:32:16 -070010326 pr.println("*** Camera timer:");
10327 mCameraOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -080010329 super.dumpLocked(context, pw, flags, reqUid, histStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010331}