blob: 87605f680d27ff962e1ac63388c525491f25ee4d [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;
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070022import android.bluetooth.BluetoothDevice;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070023import android.bluetooth.BluetoothHeadset;
Dianne Hackborna7c837f2014-01-15 16:20:44 -080024import android.content.Context;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070025import android.content.Intent;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070026import android.net.ConnectivityManager;
27import android.net.NetworkStats;
Adam Lesinski33dac552015-03-09 15:24:48 -070028import android.net.wifi.WifiActivityEnergyInfo;
Dianne Hackborn3251b902014-06-20 14:40:53 -070029import android.net.wifi.WifiManager;
Dianne Hackborn00e25212014-02-19 10:49:24 -080030import android.os.BadParcelableException;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070031import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.os.BatteryStats;
Dianne Hackborncd0e3352014-08-07 17:08:09 -070033import android.os.Build;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070034import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070035import android.os.Handler;
Jeff Brown6f357d32014-01-15 20:40:55 -080036import android.os.Looper;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070037import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.os.Parcel;
39import android.os.ParcelFormatException;
40import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070041import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.os.SystemClock;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080043import android.os.SystemProperties;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070044import android.os.WorkSource;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070045import android.telephony.DataConnectionRealTimeInfo;
Amith Yamasanif37447b2009-10-08 18:28:01 -070046import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070047import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070048import android.telephony.TelephonyManager;
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -070049import android.text.TextUtils;
Dianne Hackborn61659e52014-07-09 16:13:01 -070050import android.util.ArrayMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070052import android.util.LogWriter;
Dianne Hackbornd953c532014-08-16 18:17:38 -070053import android.util.MutableInt;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070054import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070056import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.util.SparseArray;
Dianne Hackborn099bc622014-01-22 13:39:16 -080058import android.util.SparseIntArray;
Adam Lesinskie08af192015-03-25 16:42:59 -070059import android.util.SparseLongArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070060import android.util.TimeUtils;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080061import android.util.Xml;
Jeff Browne95c3cd2014-05-02 16:59:26 -070062import android.view.Display;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070064import com.android.internal.net.NetworkStatsFactory;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080065import com.android.internal.util.ArrayUtils;
Dianne Hackborn8c841092013-06-24 13:46:13 -070066import com.android.internal.util.FastPrintWriter;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080067import com.android.internal.util.FastXmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070068import com.android.internal.util.JournaledFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080069import com.android.internal.util.XmlUtils;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070070import com.android.server.NetworkManagementSocketTagger;
71import libcore.util.EmptyArray;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080072import org.xmlpull.v1.XmlPullParser;
73import org.xmlpull.v1.XmlPullParserException;
74import org.xmlpull.v1.XmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070075
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080076import java.io.ByteArrayOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import java.io.File;
78import java.io.FileInputStream;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080079import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import java.io.FileOutputStream;
81import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070082import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import java.util.ArrayList;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080084import java.util.Calendar;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070086import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070087import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070089import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070090import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091
92/**
93 * All information we are collecting about things that can happen that impact
94 * battery life. All times are represented in microseconds except where indicated
95 * otherwise.
96 */
97public final class BatteryStatsImpl extends BatteryStats {
98 private static final String TAG = "BatteryStatsImpl";
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080099 private static final boolean DEBUG = false;
Adam Lesinskie08af192015-03-25 16:42:59 -0700100 private static final boolean DEBUG_ENERGY = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700101 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -0700102 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700103
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700104 // TODO: remove "tcp" from network methods, since we measure total stats.
105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700107 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108
109 // Current on-disk Parcel version
Kweku Adams030980a2015-04-01 16:07:48 -0700110 private static final int VERSION = 123 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700111
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700112 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700113 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700114
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700115 // No, really, THIS is the maximum number of items we will record in the history.
116 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
117
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800118 // The maximum number of names wakelocks we will keep track of
119 // per uid; once the limit is reached, we batch the remaining wakelocks
120 // in to one common name.
Dianne Hackbornacc4a122014-08-18 16:33:44 -0700121 private static final int MAX_WAKELOCKS_PER_UID = 100;
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700122
Amith Yamasanie43530a2009-08-21 13:11:37 -0700123 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700125 private final JournaledFile mFile;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700126 public final AtomicFile mCheckinFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800127 public final AtomicFile mDailyFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700129 static final int MSG_UPDATE_WAKELOCKS = 1;
130 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700131 static final int MSG_REPORT_CHARGING = 3;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700132 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700133
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700134 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
135 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
136
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:
153 if (cb != null) {
154 cb.batteryNeedsCpuUpdate();
155 }
156 break;
157 case MSG_REPORT_POWER_CHANGE:
158 if (cb != null) {
159 cb.batteryPowerChanged(msg.arg1 != 0);
160 }
161 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700162 case MSG_REPORT_CHARGING:
163 if (cb != null) {
164 final String action;
165 synchronized (BatteryStatsImpl.this) {
166 action = mCharging ? BatteryManager.ACTION_CHARGING
167 : BatteryManager.ACTION_DISCHARGING;
168 }
169 Intent intent = new Intent(action);
170 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
171 cb.batterySendBroadcast(intent);
172 }
173 break;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700174 }
175 }
176 }
177
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700178 public interface ExternalStatsSync {
179 void scheduleSync();
180 }
181
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700182 public final MyHandler mHandler;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700183 private final ExternalStatsSync mExternalSync;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700184
185 private BatteryCallback mCallback;
186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -0800188 * Mapping isolated uids to the actual owning app uid.
189 */
190 final SparseIntArray mIsolatedUids = new SparseIntArray();
191
192 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 * The statistics we have collected organized by uids.
194 */
195 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
196 new SparseArray<BatteryStatsImpl.Uid>();
197
198 // A set of pools of currently active timers. When a timer is queried, we will divide the
199 // elapsed time by the number of active timers to arrive at that timer's share of the time.
200 // In order to do this, we must refresh each timer whenever the number of active timers
201 // changes.
Adam Lesinskie08af192015-03-25 16:42:59 -0700202 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
203 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
204 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
205 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
206 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
207 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
208 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
209 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
210 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
211 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
212 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700214 // Last partial timers we use for distributing CPU usage.
Adam Lesinskie08af192015-03-25 16:42:59 -0700215 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 // These are the objects that will want to do something when the device
218 // is unplugged from power.
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800219 final TimeBase mOnBatteryTimeBase = new TimeBase();
220
221 // These are the objects that will want to do something when the device
222 // is unplugged from power *and* the screen is off.
223 final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
224
225 // Set to true when we want to distribute CPU across wakelocks for the next
226 // CPU update, even if we aren't currently running wake locks.
227 boolean mDistributeWakelockCpu;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700228
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700229 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700230
Dianne Hackborn37de0982014-05-09 09:32:18 -0700231 final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800232
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700233 long mHistoryBaseTime;
234 boolean mHaveBatteryLevel = false;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700235 boolean mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700236 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700237
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700238 static final int MAX_HISTORY_BUFFER = 256*1024; // 256KB
239 static final int MAX_MAX_HISTORY_BUFFER = 320*1024; // 320KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700240 final Parcel mHistoryBuffer = Parcel.obtain();
241 final HistoryItem mHistoryLastWritten = new HistoryItem();
242 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700243 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700244 final HistoryItem mHistoryAddTmp = new HistoryItem();
Adam Lesinskie08af192015-03-25 16:42:59 -0700245 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
Dianne Hackborn099bc622014-01-22 13:39:16 -0800246 String[] mReadHistoryStrings;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800247 int[] mReadHistoryUids;
248 int mReadHistoryChars;
249 int mNextHistoryTagIdx = 0;
250 int mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700251 int mHistoryBufferLastPos = -1;
252 boolean mHistoryOverflow = false;
Dianne Hackborn40c87252014-03-19 16:55:40 -0700253 long mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700254 long mTrackRunningHistoryElapsedRealtime = 0;
255 long mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700256
257 final HistoryItem mHistoryCur = new HistoryItem();
258
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700259 HistoryItem mHistory;
260 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700261 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700262 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700263
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800264 // Used by computeHistoryStepDetails
265 HistoryStepDetails mLastHistoryStepDetails = null;
266 byte mLastHistoryStepLevel = 0;
267 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
268 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails();
269 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
270 /**
271 * Total time (in 1/100 sec) spent executing in user code.
272 */
273 long mLastStepCpuUserTime;
274 long mCurStepCpuUserTime;
275 /**
276 * Total time (in 1/100 sec) spent executing in kernel code.
277 */
278 long mLastStepCpuSystemTime;
279 long mCurStepCpuSystemTime;
280 /**
281 * Times from /proc/stat
282 */
283 long mLastStepStatUserTime;
284 long mLastStepStatSystemTime;
285 long mLastStepStatIOWaitTime;
286 long mLastStepStatIrqTime;
287 long mLastStepStatSoftIrqTime;
288 long mLastStepStatIdleTime;
289 long mCurStepStatUserTime;
290 long mCurStepStatSystemTime;
291 long mCurStepStatIOWaitTime;
292 long mCurStepStatIrqTime;
293 long mCurStepStatSoftIrqTime;
294 long mCurStepStatIdleTime;
295
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700296 private HistoryItem mHistoryIterator;
297 private boolean mReadOverflow;
298 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 int mStartCount;
301
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800302 long mStartClockTime;
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700303 String mStartPlatformVersion;
304 String mEndPlatformVersion;
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800305
Dianne Hackborna7d0d552014-09-12 17:15:52 -0700306 long mLastRecordedClockTime;
307 long mLastRecordedClockRealtime;
308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 long mUptime;
310 long mUptimeStart;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 long mRealtime;
312 long mRealtimeStart;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700313
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800314 int mWakeLockNesting;
315 boolean mWakeLockImportant;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700316 boolean mRecordAllHistory;
Dianne Hackborn9a755432014-05-15 17:05:22 -0700317 boolean mNoAutoReset;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800318
Jeff Browne95c3cd2014-05-02 16:59:26 -0700319 int mScreenState = Display.STATE_UNKNOWN;
Evan Millarc64edde2009-04-18 12:26:32 -0700320 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700321
Dianne Hackborn617f8772009-03-31 15:04:46 -0700322 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700323 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700324
Jeff Browne95c3cd2014-05-02 16:59:26 -0700325 boolean mInteractive;
326 StopwatchTimer mInteractiveTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700327
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700328 boolean mPowerSaveModeEnabled;
329 StopwatchTimer mPowerSaveModeEnabledTimer;
330
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700331 boolean mDeviceIdling;
332 StopwatchTimer mDeviceIdlingTimer;
333
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700334 boolean mDeviceIdleModeEnabled;
335 StopwatchTimer mDeviceIdleModeEnabledTimer;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700338 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700339
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700340 int mAudioOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700341 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700342
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700343 int mVideoOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700344 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700345
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700346 boolean mFlashlightOn;
347 StopwatchTimer mFlashlightOnTimer;
348
Dianne Hackborn627bba72009-03-24 22:32:56 -0700349 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800350 int mPhoneSignalStrengthBinRaw = -1;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700351 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800352 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700353
354 StopwatchTimer mPhoneSignalScanningTimer;
355
Dianne Hackborn627bba72009-03-24 22:32:56 -0700356 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700357 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700358 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700359
Dianne Hackborn57ed6a62013-12-09 18:15:56 -0800360 final LongSamplingCounter[] mNetworkByteActivityCounters =
361 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
362 final LongSamplingCounter[] mNetworkPacketActivityCounters =
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700363 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
364
Adam Lesinski33dac552015-03-09 15:24:48 -0700365 final LongSamplingCounter[] mBluetoothActivityCounters =
366 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
367
368 final LongSamplingCounter[] mWifiActivityCounters =
369 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
370
The Android Open Source Project10592532009-03-18 17:39:46 -0700371 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700372 StopwatchTimer mWifiOnTimer;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700373
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700374 boolean mGlobalWifiRunning;
375 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700376
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800377 int mWifiState = -1;
378 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
379
Dianne Hackborn3251b902014-06-20 14:40:53 -0700380 int mWifiSupplState = -1;
381 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES];
382
383 int mWifiSignalStrengthBin = -1;
384 final StopwatchTimer[] mWifiSignalStrengthsTimer =
385 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS];
386
The Android Open Source Project10592532009-03-18 17:39:46 -0700387 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700388 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700389
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800390 int mBluetoothState = -1;
391 final StopwatchTimer[] mBluetoothStateTimer = new StopwatchTimer[NUM_BLUETOOTH_STATES];
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800392
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700393 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackbornf7097a52014-05-13 09:56:14 -0700394 long mMobileRadioActiveStartTime;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800395 StopwatchTimer mMobileRadioActiveTimer;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800396 StopwatchTimer mMobileRadioActivePerAppTimer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700397 LongSamplingCounter mMobileRadioActiveAdjustedTime;
Dianne Hackbornd45665b2014-02-26 12:35:32 -0800398 LongSamplingCounter mMobileRadioActiveUnknownTime;
399 LongSamplingCounter mMobileRadioActiveUnknownCount;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800400
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700401 /** Bluetooth headset object */
402 BluetoothHeadset mBtHeadset;
403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 /**
405 * These provide time bases that discount the time the device is plugged
406 * in to power.
407 */
408 boolean mOnBattery;
409 boolean mOnBatteryInternal;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700410
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700411 /**
412 * External reporting of whether the device is actually charging.
413 */
414 boolean mCharging = true;
415 int mLastChargingStateLevel;
416
The Android Open Source Project10592532009-03-18 17:39:46 -0700417 /*
418 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
419 */
Evan Millar633a1742009-04-02 16:36:33 -0700420 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700421 int mDischargeUnplugLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700422 int mDischargePlugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700423 int mDischargeCurrentLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700424 int mCurrentBatteryLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700425 int mLowDischargeAmountSinceCharge;
426 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800427 int mDischargeScreenOnUnplugLevel;
428 int mDischargeScreenOffUnplugLevel;
429 int mDischargeAmountScreenOn;
430 int mDischargeAmountScreenOnSinceCharge;
431 int mDischargeAmountScreenOff;
432 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700433
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700434 static final int MAX_LEVEL_STEPS = 200;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700435
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700436 int mInitStepMode = 0;
437 int mCurStepMode = 0;
438 int mModStepMode = 0;
439
Dianne Hackborn260c5022014-04-29 11:23:16 -0700440 int mLastDischargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700441 int mMinDischargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800442 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
443 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700444 ArrayList<PackageChange> mDailyPackageChanges;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700445
446 int mLastChargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700447 int mMaxChargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800448 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
449 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
450
451 static final int MAX_DAILY_ITEMS = 10;
452
453 long mDailyStartTime = 0;
454 long mNextMinDailyDeadline = 0;
455 long mNextMaxDailyDeadline = 0;
456
457 final ArrayList<DailyItem> mDailyItems = new ArrayList<>();
Dianne Hackborn260c5022014-04-29 11:23:16 -0700458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700460
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700461 private int mBluetoothPingCount;
462 private int mBluetoothPingStart = -1;
463
Amith Yamasanif37447b2009-10-08 18:28:01 -0700464 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800465 private int mPhoneServiceStateRaw = -1;
466 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700467
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800468 private int mNumConnectivityChange;
469 private int mLoadedNumConnectivityChange;
470 private int mUnpluggedNumConnectivityChange;
471
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700472 private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
473
Adam Lesinskie08af192015-03-25 16:42:59 -0700474 private PowerProfile mPowerProfile;
Adam Lesinski17390762015-04-10 13:17:47 -0700475 private boolean mHasWifiEnergyReporting = false;
476 private boolean mHasBluetoothEnergyReporting = false;
Adam Lesinskie08af192015-03-25 16:42:59 -0700477
Evan Millarc64edde2009-04-18 12:26:32 -0700478 /*
479 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
480 */
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700481 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700482
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700483 public Map<String, ? extends Timer> getKernelWakelockStats() {
Evan Millarc64edde2009-04-18 12:26:32 -0700484 return mKernelWakelockStats;
485 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700486
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700487 String mLastWakeupReason = null;
488 long mLastWakeupUptimeMs = 0;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700489 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700490
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700491 public Map<String, ? extends Timer> getWakeupReasonStats() {
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700492 return mWakeupReasonStats;
493 }
494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700496 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700497 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800498 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700499 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700500 mExternalSync = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700501 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 }
503
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800504 public static interface TimeBaseObs {
505 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
506 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
507 }
508
509 static class TimeBase {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700510 private final ArrayList<TimeBaseObs> mObservers = new ArrayList<>();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800511
512 private long mUptime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800513 private long mRealtime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800514
515 private boolean mRunning;
516
517 private long mPastUptime;
518 private long mUptimeStart;
519 private long mPastRealtime;
520 private long mRealtimeStart;
521 private long mUnpluggedUptime;
522 private long mUnpluggedRealtime;
523
524 public void dump(PrintWriter pw, String prefix) {
525 StringBuilder sb = new StringBuilder(128);
526 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
527 sb.setLength(0);
528 sb.append(prefix);
529 sb.append("mUptime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700530 formatTimeMs(sb, mUptime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800531 pw.println(sb.toString());
532 sb.setLength(0);
533 sb.append(prefix);
534 sb.append("mRealtime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700535 formatTimeMs(sb, mRealtime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800536 pw.println(sb.toString());
537 sb.setLength(0);
538 sb.append(prefix);
539 sb.append("mPastUptime=");
540 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
541 formatTimeMs(sb, mUptimeStart / 1000);
542 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
543 pw.println(sb.toString());
544 sb.setLength(0);
545 sb.append(prefix);
546 sb.append("mPastRealtime=");
547 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
548 formatTimeMs(sb, mRealtimeStart / 1000);
549 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
550 pw.println(sb.toString());
551 }
552
553 public void add(TimeBaseObs observer) {
554 mObservers.add(observer);
555 }
556
557 public void remove(TimeBaseObs observer) {
558 if (!mObservers.remove(observer)) {
559 Slog.wtf(TAG, "Removed unknown observer: " + observer);
560 }
561 }
562
563 public void init(long uptime, long realtime) {
564 mRealtime = 0;
565 mUptime = 0;
566 mPastUptime = 0;
567 mPastRealtime = 0;
568 mUptimeStart = uptime;
569 mRealtimeStart = realtime;
570 mUnpluggedUptime = getUptime(mUptimeStart);
571 mUnpluggedRealtime = getRealtime(mRealtimeStart);
572 }
573
574 public void reset(long uptime, long realtime) {
575 if (!mRunning) {
576 mPastUptime = 0;
577 mPastRealtime = 0;
578 } else {
579 mUptimeStart = uptime;
580 mRealtimeStart = realtime;
581 mUnpluggedUptime = getUptime(uptime);
582 mUnpluggedRealtime = getRealtime(realtime);
583 }
584 }
585
586 public long computeUptime(long curTime, int which) {
587 switch (which) {
588 case STATS_SINCE_CHARGED:
589 return mUptime + getUptime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800590 case STATS_CURRENT:
591 return getUptime(curTime);
592 case STATS_SINCE_UNPLUGGED:
593 return getUptime(curTime) - mUnpluggedUptime;
594 }
595 return 0;
596 }
597
598 public long computeRealtime(long curTime, int which) {
599 switch (which) {
600 case STATS_SINCE_CHARGED:
601 return mRealtime + getRealtime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800602 case STATS_CURRENT:
603 return getRealtime(curTime);
604 case STATS_SINCE_UNPLUGGED:
605 return getRealtime(curTime) - mUnpluggedRealtime;
606 }
607 return 0;
608 }
609
610 public long getUptime(long curTime) {
611 long time = mPastUptime;
612 if (mRunning) {
613 time += curTime - mUptimeStart;
614 }
615 return time;
616 }
617
618 public long getRealtime(long curTime) {
619 long time = mPastRealtime;
620 if (mRunning) {
621 time += curTime - mRealtimeStart;
622 }
623 return time;
624 }
625
626 public long getUptimeStart() {
627 return mUptimeStart;
628 }
629
630 public long getRealtimeStart() {
631 return mRealtimeStart;
632 }
633
634 public boolean isRunning() {
635 return mRunning;
636 }
637
638 public boolean setRunning(boolean running, long uptime, long realtime) {
639 if (mRunning != running) {
640 mRunning = running;
641 if (running) {
642 mUptimeStart = uptime;
643 mRealtimeStart = realtime;
644 long batteryUptime = mUnpluggedUptime = getUptime(uptime);
645 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
646
647 for (int i = mObservers.size() - 1; i >= 0; i--) {
648 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
649 }
650 } else {
651 mPastUptime += uptime - mUptimeStart;
652 mPastRealtime += realtime - mRealtimeStart;
653
654 long batteryUptime = getUptime(uptime);
655 long batteryRealtime = getRealtime(realtime);
656
657 for (int i = mObservers.size() - 1; i >= 0; i--) {
658 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
659 }
660 }
661 return true;
662 }
663 return false;
664 }
665
666 public void readSummaryFromParcel(Parcel in) {
667 mUptime = in.readLong();
668 mRealtime = in.readLong();
669 }
670
671 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
672 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
673 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
674 }
675
676 public void readFromParcel(Parcel in) {
677 mRunning = false;
678 mUptime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800679 mPastUptime = in.readLong();
680 mUptimeStart = in.readLong();
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700681 mRealtime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800682 mPastRealtime = in.readLong();
683 mRealtimeStart = in.readLong();
684 mUnpluggedUptime = in.readLong();
685 mUnpluggedRealtime = in.readLong();
686 }
687
688 public void writeToParcel(Parcel out, long uptime, long realtime) {
689 final long runningUptime = getUptime(uptime);
690 final long runningRealtime = getRealtime(realtime);
691 out.writeLong(mUptime);
692 out.writeLong(runningUptime);
693 out.writeLong(mUptimeStart);
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700694 out.writeLong(mRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800695 out.writeLong(runningRealtime);
696 out.writeLong(mRealtimeStart);
697 out.writeLong(mUnpluggedUptime);
698 out.writeLong(mUnpluggedRealtime);
699 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700703 * State for keeping track of counting information.
704 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800705 public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
Christopher Tate4cee7252010-03-19 14:50:40 -0700706 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800707 final TimeBase mTimeBase;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700708 int mLoadedCount;
709 int mLastCount;
710 int mUnpluggedCount;
711 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700712
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800713 Counter(TimeBase timeBase, Parcel in) {
714 mTimeBase = timeBase;
Christopher Tate4cee7252010-03-19 14:50:40 -0700715 mPluggedCount = in.readInt();
716 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700717 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700718 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700719 mUnpluggedCount = in.readInt();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800720 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700721 }
722
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800723 Counter(TimeBase timeBase) {
724 mTimeBase = timeBase;
725 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700726 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700727
Dianne Hackborn617f8772009-03-31 15:04:46 -0700728 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700729 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700730 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700731 out.writeInt(mUnpluggedCount);
732 }
733
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800734 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700735 mUnpluggedCount = mPluggedCount;
736 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700737 }
738
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800739 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700740 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700741 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700742
Dianne Hackborn617f8772009-03-31 15:04:46 -0700743 /**
744 * Writes a possibly null Counter to a Parcel.
745 *
746 * @param out the Parcel to be written to.
747 * @param counter a Counter, or null.
748 */
749 public static void writeCounterToParcel(Parcel out, Counter counter) {
750 if (counter == null) {
751 out.writeInt(0); // indicates null
752 return;
753 }
754 out.writeInt(1); // indicates non-null
755
756 counter.writeToParcel(out);
757 }
758
759 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700760 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700761 int val = mCount.get();
762 if (which == STATS_SINCE_UNPLUGGED) {
763 val -= mUnpluggedCount;
764 } else if (which != STATS_SINCE_CHARGED) {
765 val -= mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700766 }
767
768 return val;
769 }
770
771 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700772 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700773 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
774 + " mUnpluggedCount=" + mUnpluggedCount
775 + " mPluggedCount=" + mPluggedCount);
776 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700777
Christopher Tate4cee7252010-03-19 14:50:40 -0700778 void stepAtomic() {
779 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700780 }
781
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700782 /**
783 * Clear state of this counter.
784 */
785 void reset(boolean detachIfReset) {
786 mCount.set(0);
787 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
788 if (detachIfReset) {
789 detach();
790 }
791 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700792
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700793 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800794 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700795 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700796
Dianne Hackborn617f8772009-03-31 15:04:46 -0700797 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700798 int count = mCount.get();
799 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700800 }
801
802 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700803 mLoadedCount = in.readInt();
804 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700805 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700806 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700807 }
808 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700809
810 public static class SamplingCounter extends Counter {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800811 SamplingCounter(TimeBase timeBase, Parcel in) {
812 super(timeBase, in);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700813 }
814
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800815 SamplingCounter(TimeBase timeBase) {
816 super(timeBase);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700817 }
818
Christopher Tate4cee7252010-03-19 14:50:40 -0700819 public void addCountAtomic(long count) {
820 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700821 }
822 }
823
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700824 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800825 final TimeBase mTimeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700826 long mCount;
827 long mLoadedCount;
828 long mLastCount;
829 long mUnpluggedCount;
830 long mPluggedCount;
831
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800832 LongSamplingCounter(TimeBase timeBase, Parcel in) {
833 mTimeBase = timeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700834 mPluggedCount = in.readLong();
835 mCount = mPluggedCount;
836 mLoadedCount = in.readLong();
837 mLastCount = 0;
838 mUnpluggedCount = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800839 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700840 }
841
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800842 LongSamplingCounter(TimeBase timeBase) {
843 mTimeBase = timeBase;
844 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700845 }
846
847 public void writeToParcel(Parcel out) {
848 out.writeLong(mCount);
849 out.writeLong(mLoadedCount);
850 out.writeLong(mUnpluggedCount);
851 }
852
853 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800854 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700855 mUnpluggedCount = mPluggedCount;
856 mCount = mPluggedCount;
857 }
858
859 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800860 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700861 mPluggedCount = mCount;
862 }
863
864 public long getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700865 long val = mCount;
866 if (which == STATS_SINCE_UNPLUGGED) {
867 val -= mUnpluggedCount;
868 } else if (which != STATS_SINCE_CHARGED) {
869 val -= mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700870 }
871
872 return val;
873 }
874
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700875 @Override
876 public void logState(Printer pw, String prefix) {
877 pw.println(prefix + "mCount=" + mCount
878 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
879 + " mUnpluggedCount=" + mUnpluggedCount
880 + " mPluggedCount=" + mPluggedCount);
881 }
882
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700883 void addCountLocked(long count) {
884 mCount += count;
885 }
886
887 /**
888 * Clear state of this counter.
889 */
890 void reset(boolean detachIfReset) {
891 mCount = 0;
892 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
893 if (detachIfReset) {
894 detach();
895 }
896 }
897
898 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800899 mTimeBase.remove(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700900 }
901
902 void writeSummaryFromParcelLocked(Parcel out) {
903 out.writeLong(mCount);
904 }
905
906 void readSummaryFromParcelLocked(Parcel in) {
907 mLoadedCount = in.readLong();
908 mCount = mLoadedCount;
909 mLastCount = 0;
910 mUnpluggedCount = mPluggedCount = mLoadedCount;
911 }
912 }
913
Dianne Hackborn617f8772009-03-31 15:04:46 -0700914 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 * State for keeping track of timing information.
916 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800917 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 final int mType;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800919 final TimeBase mTimeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 int mCount;
922 int mLoadedCount;
923 int mLastCount;
924 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 // Times are in microseconds for better accuracy when dividing by the
927 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 /**
930 * The total time we have accumulated since the start of the original
931 * boot, to the last time something interesting happened in the
932 * current run.
933 */
934 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 /**
937 * The total time we loaded for the previous runs. Subtract this from
938 * mTotalTime to find the time for the current run of the system.
939 */
940 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700941
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 /**
943 * The run time of the last run of the system, as loaded from the
944 * saved data.
945 */
946 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 /**
949 * The value of mTotalTime when unplug() was last called. Subtract
950 * this from mTotalTime to find the time since the last unplug from
951 * power.
952 */
953 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700954
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700955 /**
Adam Lesinskie08af192015-03-25 16:42:59 -0700956 * The total time this timer has been running until the latest mark has been set.
957 * Subtract this from mTotalTime to get the time spent running since the mark was set.
958 */
959 long mTimeBeforeMark;
960
961 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700962 * Constructs from a parcel.
963 * @param type
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800964 * @param timeBase
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700965 * @param in
966 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800967 Timer(int type, TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800969 mTimeBase = timeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 mCount = in.readInt();
972 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700973 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 mUnpluggedCount = in.readInt();
975 mTotalTime = in.readLong();
976 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700977 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 mUnpluggedTime = in.readLong();
Adam Lesinskie08af192015-03-25 16:42:59 -0700979 mTimeBeforeMark = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800980 timeBase.add(this);
Dianne Hackborn29325132014-05-21 15:01:03 -0700981 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 }
983
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800984 Timer(int type, TimeBase timeBase) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800986 mTimeBase = timeBase;
987 timeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 }
Evan Millarc64edde2009-04-18 12:26:32 -0700989
990 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700991
Evan Millarc64edde2009-04-18 12:26:32 -0700992 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700993
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700994 /**
995 * Clear state of this timer. Returns true if the timer is inactive
996 * so can be completely dropped.
997 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800998 boolean reset(boolean detachIfReset) {
Adam Lesinskie08af192015-03-25 16:42:59 -0700999 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001000 mCount = mLoadedCount = mLastCount = 0;
1001 if (detachIfReset) {
1002 detach();
1003 }
1004 return true;
1005 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001006
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001007 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001008 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001009 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001010
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001011 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
Dianne Hackborn29325132014-05-21 15:01:03 -07001012 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
1013 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 out.writeInt(mCount);
1015 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 out.writeInt(mUnpluggedCount);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001017 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 out.writeLong(mUnpluggedTime);
Adam Lesinskie08af192015-03-25 16:42:59 -07001020 out.writeLong(mTimeBeforeMark);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 }
1022
Adam Lesinskie08af192015-03-25 16:42:59 -07001023 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001024 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001026 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 + " old mUnpluggedTime=" + mUnpluggedTime
1028 + " old mUnpluggedCount=" + mUnpluggedCount);
1029 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001030 mUnpluggedTime = computeRunTimeLocked(baseRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 mUnpluggedCount = mCount;
1032 if (DEBUG && mType < 0) {
1033 Log.v(TAG, "unplug #" + mType
1034 + ": new mUnpluggedTime=" + mUnpluggedTime
1035 + " new mUnpluggedCount=" + mUnpluggedCount);
1036 }
1037 }
1038
Adam Lesinskie08af192015-03-25 16:42:59 -07001039 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001040 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001041 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001042 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
Evan Millarc64edde2009-04-18 12:26:32 -07001043 + " old mTotalTime=" + mTotalTime);
1044 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001045 mTotalTime = computeRunTimeLocked(baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001046 mCount = computeCurrentCountLocked();
1047 if (DEBUG && mType < 0) {
1048 Log.v(TAG, "plug #" + mType
1049 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 }
1051 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 /**
1054 * Writes a possibly null Timer to a Parcel.
1055 *
1056 * @param out the Parcel to be written to.
1057 * @param timer a Timer, or null.
1058 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001059 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 if (timer == null) {
1061 out.writeInt(0); // indicates null
1062 return;
1063 }
1064 out.writeInt(1); // indicates non-null
1065
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001066 timer.writeToParcel(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 }
1068
1069 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001070 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001071 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1072 if (which == STATS_SINCE_UNPLUGGED) {
1073 val -= mUnpluggedTime;
1074 } else if (which != STATS_SINCE_CHARGED) {
1075 val -= mLoadedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001076 }
1077
1078 return val;
1079 }
1080
1081 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001082 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001083 int val = computeCurrentCountLocked();
1084 if (which == STATS_SINCE_UNPLUGGED) {
1085 val -= mUnpluggedCount;
1086 } else if (which != STATS_SINCE_CHARGED) {
1087 val -= mLoadedCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 }
1089
1090 return val;
1091 }
1092
Adam Lesinskie08af192015-03-25 16:42:59 -07001093 @Override
1094 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) {
1095 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1096 return val - mTimeBeforeMark;
1097 }
1098
1099 @Override
Dianne Hackborn627bba72009-03-24 22:32:56 -07001100 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001101 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
1103 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001104 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001106 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001108 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001109
1110
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001111 void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
1112 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1113 out.writeLong(runTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001114 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -07001115 }
1116
1117 void readSummaryFromParcelLocked(Parcel in) {
1118 // Multiply by 1000 for backwards compatibility
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001119 mTotalTime = mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001120 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001121 mUnpluggedTime = mTotalTime;
1122 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001123 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001124 mUnpluggedCount = mCount;
Adam Lesinskie08af192015-03-25 16:42:59 -07001125
1126 // When reading the summary, we set the mark to be the latest information.
1127 mTimeBeforeMark = mTotalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001128 }
1129 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001130
Evan Millarc64edde2009-04-18 12:26:32 -07001131 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001132
Evan Millarc64edde2009-04-18 12:26:32 -07001133 /**
1134 * The most recent reported count from /proc/wakelocks.
1135 */
1136 int mCurrentReportedCount;
1137
1138 /**
1139 * The reported count from /proc/wakelocks when unplug() was last
1140 * called.
1141 */
1142 int mUnpluggedReportedCount;
1143
1144 /**
1145 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001146 */
Evan Millarc64edde2009-04-18 12:26:32 -07001147 long mCurrentReportedTotalTime;
1148
1149
1150 /**
1151 * The reported total_time from /proc/wakelocks when unplug() was last
1152 * called.
1153 */
1154 long mUnpluggedReportedTotalTime;
1155
1156 /**
1157 * Whether we are currently in a discharge cycle.
1158 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001159 boolean mTimeBaseRunning;
Evan Millarc64edde2009-04-18 12:26:32 -07001160
1161 /**
1162 * Whether we are currently recording reported values.
1163 */
1164 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001165
Evan Millarc64edde2009-04-18 12:26:32 -07001166 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001167 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -07001168 */
1169 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001170
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001171 SamplingTimer(TimeBase timeBase, Parcel in) {
1172 super(0, timeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07001173 mCurrentReportedCount = in.readInt();
1174 mUnpluggedReportedCount = in.readInt();
1175 mCurrentReportedTotalTime = in.readLong();
1176 mUnpluggedReportedTotalTime = in.readLong();
1177 mTrackingReportedValues = in.readInt() == 1;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001178 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001179 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001180
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001181 SamplingTimer(TimeBase timeBase, boolean trackReportedValues) {
1182 super(0, timeBase);
Evan Millarc64edde2009-04-18 12:26:32 -07001183 mTrackingReportedValues = trackReportedValues;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001184 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001185 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001186
Evan Millarc64edde2009-04-18 12:26:32 -07001187 public void setStale() {
1188 mTrackingReportedValues = false;
1189 mUnpluggedReportedTotalTime = 0;
1190 mUnpluggedReportedCount = 0;
1191 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001192
Evan Millarc64edde2009-04-18 12:26:32 -07001193 public void setUpdateVersion(int version) {
1194 mUpdateVersion = version;
1195 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001196
Evan Millarc64edde2009-04-18 12:26:32 -07001197 public int getUpdateVersion() {
1198 return mUpdateVersion;
1199 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001200
Evan Millarc64edde2009-04-18 12:26:32 -07001201 public void updateCurrentReportedCount(int count) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001202 if (mTimeBaseRunning && mUnpluggedReportedCount == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001203 // Updating the reported value for the first time.
1204 mUnpluggedReportedCount = count;
1205 // If we are receiving an update update mTrackingReportedValues;
1206 mTrackingReportedValues = true;
1207 }
1208 mCurrentReportedCount = count;
1209 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001210
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001211 public void addCurrentReportedCount(int delta) {
1212 updateCurrentReportedCount(mCurrentReportedCount + delta);
1213 }
1214
Evan Millarc64edde2009-04-18 12:26:32 -07001215 public void updateCurrentReportedTotalTime(long totalTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001216 if (mTimeBaseRunning && mUnpluggedReportedTotalTime == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001217 // Updating the reported value for the first time.
1218 mUnpluggedReportedTotalTime = totalTime;
1219 // If we are receiving an update update mTrackingReportedValues;
1220 mTrackingReportedValues = true;
1221 }
1222 mCurrentReportedTotalTime = totalTime;
1223 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001224
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001225 public void addCurrentReportedTotalTime(long delta) {
1226 updateCurrentReportedTotalTime(mCurrentReportedTotalTime + delta);
1227 }
1228
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001229 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1230 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001231 if (mTrackingReportedValues) {
1232 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
1233 mUnpluggedReportedCount = mCurrentReportedCount;
1234 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001235 mTimeBaseRunning = true;
Evan Millarc64edde2009-04-18 12:26:32 -07001236 }
1237
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001238 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1239 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1240 mTimeBaseRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001241 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001242
Evan Millarc64edde2009-04-18 12:26:32 -07001243 public void logState(Printer pw, String prefix) {
1244 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001245 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -07001246 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
1247 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
1248 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
1249 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001250
Evan Millarc64edde2009-04-18 12:26:32 -07001251 protected long computeRunTimeLocked(long curBatteryRealtime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001252 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001253 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
1254 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001255
Evan Millarc64edde2009-04-18 12:26:32 -07001256 protected int computeCurrentCountLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001257 return mCount + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001258 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
1259 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001260
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001261 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1262 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001263 out.writeInt(mCurrentReportedCount);
1264 out.writeInt(mUnpluggedReportedCount);
1265 out.writeLong(mCurrentReportedTotalTime);
1266 out.writeLong(mUnpluggedReportedTotalTime);
1267 out.writeInt(mTrackingReportedValues ? 1 : 0);
1268 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001269
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001270 boolean reset(boolean detachIfReset) {
1271 super.reset(detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001272 setStale();
1273 return true;
1274 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001275
Evan Millarc64edde2009-04-18 12:26:32 -07001276 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
1277 super.writeSummaryFromParcelLocked(out, batteryRealtime);
1278 out.writeLong(mCurrentReportedTotalTime);
1279 out.writeInt(mCurrentReportedCount);
1280 out.writeInt(mTrackingReportedValues ? 1 : 0);
1281 }
1282
1283 void readSummaryFromParcelLocked(Parcel in) {
1284 super.readSummaryFromParcelLocked(in);
1285 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
1286 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
1287 mTrackingReportedValues = in.readInt() == 1;
1288 }
1289 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001290
Evan Millarc64edde2009-04-18 12:26:32 -07001291 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001292 * A timer that increments in batches. It does not run for durations, but just jumps
1293 * for a pre-determined amount.
1294 */
1295 public static final class BatchTimer extends Timer {
1296 final Uid mUid;
1297
1298 /**
1299 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
1300 */
1301 long mLastAddedTime;
1302
1303 /**
1304 * The last duration that we added to the timer. This is in microseconds.
1305 */
1306 long mLastAddedDuration;
1307
1308 /**
1309 * Whether we are currently in a discharge cycle.
1310 */
1311 boolean mInDischarge;
1312
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001313 BatchTimer(Uid uid, int type, TimeBase timeBase, Parcel in) {
1314 super(type, timeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001315 mUid = uid;
1316 mLastAddedTime = in.readLong();
1317 mLastAddedDuration = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001318 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001319 }
1320
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001321 BatchTimer(Uid uid, int type, TimeBase timeBase) {
1322 super(type, timeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001323 mUid = uid;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001324 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001325 }
1326
1327 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001328 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1329 super.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001330 out.writeLong(mLastAddedTime);
1331 out.writeLong(mLastAddedDuration);
1332 }
1333
1334 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001335 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001336 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
1337 mInDischarge = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001338 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001339 }
1340
1341 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001342 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001343 recomputeLastDuration(elapsedRealtime, false);
1344 mInDischarge = true;
1345 // If we are still within the last added duration, then re-added whatever remains.
1346 if (mLastAddedTime == elapsedRealtime) {
1347 mTotalTime += mLastAddedDuration;
1348 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001349 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001350 }
1351
1352 @Override
1353 public void logState(Printer pw, String prefix) {
1354 super.logState(pw, prefix);
1355 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
1356 + " mLastAddedDuration=" + mLastAddedDuration);
1357 }
1358
1359 private long computeOverage(long curTime) {
1360 if (mLastAddedTime > 0) {
1361 return mLastTime + mLastAddedDuration - curTime;
1362 }
1363 return 0;
1364 }
1365
1366 private void recomputeLastDuration(long curTime, boolean abort) {
1367 final long overage = computeOverage(curTime);
1368 if (overage > 0) {
1369 // Aborting before the duration ran out -- roll back the remaining
1370 // duration. Only do this if currently discharging; otherwise we didn't
1371 // actually add the time.
1372 if (mInDischarge) {
1373 mTotalTime -= overage;
1374 }
1375 if (abort) {
1376 mLastAddedTime = 0;
1377 } else {
1378 mLastAddedTime = curTime;
1379 mLastAddedDuration -= overage;
1380 }
1381 }
1382 }
1383
1384 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
1385 final long now = SystemClock.elapsedRealtime() * 1000;
1386 recomputeLastDuration(now, true);
1387 mLastAddedTime = now;
1388 mLastAddedDuration = durationMillis * 1000;
1389 if (mInDischarge) {
1390 mTotalTime += mLastAddedDuration;
1391 mCount++;
1392 }
1393 }
1394
1395 public void abortLastDuration(BatteryStatsImpl stats) {
1396 final long now = SystemClock.elapsedRealtime() * 1000;
1397 recomputeLastDuration(now, true);
1398 }
1399
1400 @Override
1401 protected int computeCurrentCountLocked() {
1402 return mCount;
1403 }
1404
1405 @Override
1406 protected long computeRunTimeLocked(long curBatteryRealtime) {
1407 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000);
1408 if (overage > 0) {
1409 return mTotalTime = overage;
1410 }
1411 return mTotalTime;
1412 }
1413
1414 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001415 boolean reset(boolean detachIfReset) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001416 final long now = SystemClock.elapsedRealtime() * 1000;
1417 recomputeLastDuration(now, true);
1418 boolean stillActive = mLastAddedTime == now;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001419 super.reset(!stillActive && detachIfReset);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001420 return !stillActive;
1421 }
1422 }
1423
1424 /**
Evan Millarc64edde2009-04-18 12:26:32 -07001425 * State for keeping track of timing information.
1426 */
1427 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001428 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07001429 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001430
Evan Millarc64edde2009-04-18 12:26:32 -07001431 int mNesting;
1432
Evan Millarc64edde2009-04-18 12:26:32 -07001433 /**
1434 * The last time at which we updated the timer. If mNesting is > 0,
1435 * subtract this from the current battery time to find the amount of
1436 * time we have been running since we last computed an update.
1437 */
1438 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001439
Evan Millarc64edde2009-04-18 12:26:32 -07001440 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001441 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -07001442 * was actually held for an interesting duration.
1443 */
1444 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001445
Amith Yamasanif37447b2009-10-08 18:28:01 -07001446 long mTimeout;
1447
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001448 /**
1449 * For partial wake locks, keep track of whether we are in the list
1450 * to consume CPU cycles.
1451 */
1452 boolean mInList;
1453
1454 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001455 TimeBase timeBase, Parcel in) {
1456 super(type, timeBase, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001457 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001458 mTimerPool = timerPool;
1459 mUpdateTime = in.readLong();
1460 }
1461
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001462 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001463 TimeBase timeBase) {
1464 super(type, timeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001465 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001466 mTimerPool = timerPool;
1467 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001468
Amith Yamasanif37447b2009-10-08 18:28:01 -07001469 void setTimeout(long timeout) {
1470 mTimeout = timeout;
1471 }
1472
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001473 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1474 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001475 out.writeLong(mUpdateTime);
1476 }
1477
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001478 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001479 if (mNesting > 0) {
1480 if (DEBUG && mType < 0) {
1481 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
1482 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001483 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1484 mUpdateTime = baseRealtime;
Evan Millarc64edde2009-04-18 12:26:32 -07001485 if (DEBUG && mType < 0) {
1486 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
1487 }
1488 }
1489 }
1490
1491 public void logState(Printer pw, String prefix) {
1492 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001493 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 + " mAcquireTime=" + mAcquireTime);
1495 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001496
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001497 void startRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 if (mNesting++ == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001499 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001500 mUpdateTime = batteryRealtime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 if (mTimerPool != null) {
1502 // Accumulate time to all currently active timers before adding
1503 // this new one to the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001504 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 // Add this timer to the active pool
1506 mTimerPool.add(this);
1507 }
1508 // Increment the count
1509 mCount++;
1510 mAcquireTime = mTotalTime;
1511 if (DEBUG && mType < 0) {
1512 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
1513 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1514 + " mAcquireTime=" + mAcquireTime);
1515 }
1516 }
1517 }
1518
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001519 boolean isRunningLocked() {
1520 return mNesting > 0;
1521 }
1522
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001523 void stopRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001524 // Ignore attempt to stop a timer that isn't running
1525 if (mNesting == 0) {
1526 return;
1527 }
1528 if (--mNesting == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001529 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 if (mTimerPool != null) {
1531 // Accumulate time to all active counters, scaled by the total
1532 // active in the pool, before taking this one out of the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001533 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 // Remove this timer from the active pool
1535 mTimerPool.remove(this);
1536 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 mNesting = 1;
1538 mTotalTime = computeRunTimeLocked(batteryRealtime);
1539 mNesting = 0;
1540 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 if (DEBUG && mType < 0) {
1543 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
1544 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1545 + " mAcquireTime=" + mAcquireTime);
1546 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 if (mTotalTime == mAcquireTime) {
1549 // If there was no change in the time, then discard this
1550 // count. A somewhat cheezy strategy, but hey.
1551 mCount--;
1552 }
1553 }
1554 }
1555
Dianne Hackborn10eaa852014-07-22 22:54:55 -07001556 void stopAllRunningLocked(long elapsedRealtimeMs) {
1557 if (mNesting > 0) {
1558 mNesting = 1;
1559 stopRunningLocked(elapsedRealtimeMs);
1560 }
1561 }
1562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 // Update the total time for all other running Timers with the same type as this Timer
1564 // due to a change in timer count
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001565 private static long refreshTimersLocked(long batteryRealtime,
1566 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001567 long selfTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 final int N = pool.size();
1569 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07001570 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 long heldTime = batteryRealtime - t.mUpdateTime;
1572 if (heldTime > 0) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001573 final long myTime = heldTime / N;
1574 if (t == self) {
1575 selfTime = myTime;
1576 }
1577 t.mTotalTime += myTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001578 }
1579 t.mUpdateTime = batteryRealtime;
1580 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001581 return selfTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 }
1583
Evan Millarc64edde2009-04-18 12:26:32 -07001584 @Override
1585 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001586 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
1587 curBatteryRealtime = mUpdateTime + mTimeout;
1588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 return mTotalTime + (mNesting > 0
1590 ? (curBatteryRealtime - mUpdateTime)
1591 / (mTimerPool != null ? mTimerPool.size() : 1)
1592 : 0);
1593 }
1594
Evan Millarc64edde2009-04-18 12:26:32 -07001595 @Override
1596 protected int computeCurrentCountLocked() {
1597 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598 }
1599
Adam Lesinskie08af192015-03-25 16:42:59 -07001600 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001601 boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001602 boolean canDetach = mNesting <= 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001603 super.reset(canDetach && detachIfReset);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001604 if (mNesting > 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001605 mUpdateTime = mTimeBase.getRealtime(SystemClock.elapsedRealtime() * 1000);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001606 }
1607 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001608 return canDetach;
1609 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001610
Adam Lesinskie08af192015-03-25 16:42:59 -07001611 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001612 void detach() {
1613 super.detach();
1614 if (mTimerPool != null) {
1615 mTimerPool.remove(this);
1616 }
1617 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001618
Adam Lesinskie08af192015-03-25 16:42:59 -07001619 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001621 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 mNesting = 0;
1623 }
Adam Lesinskie08af192015-03-25 16:42:59 -07001624
1625 /**
1626 * Set the mark so that we can query later for the total time the timer has
1627 * accumulated since this point. The timer can be running or not.
1628 *
1629 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds.
1630 */
1631 public void setMark(long elapsedRealtimeMs) {
1632 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
1633 if (mNesting > 0) {
1634 // We are running.
1635 if (mTimerPool != null) {
1636 refreshTimersLocked(batteryRealtime, mTimerPool, this);
1637 } else {
1638 mTotalTime += batteryRealtime - mUpdateTime;
1639 mUpdateTime = batteryRealtime;
1640 }
1641 }
1642 mTimeBeforeMark = mTotalTime;
1643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001644 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001645
Dianne Hackbornd953c532014-08-16 18:17:38 -07001646 public abstract class OverflowArrayMap<T> {
1647 private static final String OVERFLOW_NAME = "*overflow*";
1648
1649 final ArrayMap<String, T> mMap = new ArrayMap<>();
1650 T mCurOverflow;
1651 ArrayMap<String, MutableInt> mActiveOverflow;
1652
1653 public OverflowArrayMap() {
1654 }
1655
1656 public ArrayMap<String, T> getMap() {
1657 return mMap;
1658 }
1659
1660 public void clear() {
1661 mMap.clear();
1662 mCurOverflow = null;
1663 mActiveOverflow = null;
1664 }
1665
1666 public void add(String name, T obj) {
1667 mMap.put(name, obj);
1668 if (OVERFLOW_NAME.equals(name)) {
1669 mCurOverflow = obj;
1670 }
1671 }
1672
1673 public void cleanup() {
1674 if (mActiveOverflow != null) {
1675 if (mActiveOverflow.size() == 0) {
1676 mActiveOverflow = null;
1677 }
1678 }
1679 if (mActiveOverflow == null) {
1680 // There is no currently active overflow, so we should no longer have
1681 // an overflow entry.
1682 if (mMap.containsKey(OVERFLOW_NAME)) {
1683 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry "
1684 + mMap.get(OVERFLOW_NAME));
1685 mMap.remove(OVERFLOW_NAME);
1686 }
1687 mCurOverflow = null;
1688 } else {
1689 // There is currently active overflow, so we should still have an overflow entry.
1690 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) {
1691 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur="
1692 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME));
1693 }
1694 }
1695 }
1696
1697 public T startObject(String name) {
1698 T obj = mMap.get(name);
1699 if (obj != null) {
1700 return obj;
1701 }
1702
1703 // No object exists for the given name, but do we currently have it
1704 // running as part of the overflow?
1705 if (mActiveOverflow != null) {
1706 MutableInt over = mActiveOverflow.get(name);
1707 if (over != null) {
1708 // We are already actively counting this name in the overflow object.
1709 obj = mCurOverflow;
1710 if (obj == null) {
1711 // Shouldn't be here, but we'll try to recover.
1712 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow");
1713 obj = mCurOverflow = instantiateObject();
1714 mMap.put(OVERFLOW_NAME, obj);
1715 }
1716 over.value++;
1717 return obj;
1718 }
1719 }
1720
1721 // No object exists for given name nor in the overflow; we need to make
1722 // a new one.
1723 final int N = mMap.size();
1724 if (N >= MAX_WAKELOCKS_PER_UID) {
1725 // Went over the limit on number of objects to track; this one goes
1726 // in to the overflow.
1727 obj = mCurOverflow;
1728 if (obj == null) {
1729 // Need to start overflow now...
1730 obj = mCurOverflow = instantiateObject();
1731 mMap.put(OVERFLOW_NAME, obj);
1732 }
1733 if (mActiveOverflow == null) {
1734 mActiveOverflow = new ArrayMap<>();
1735 }
1736 mActiveOverflow.put(name, new MutableInt(1));
1737 return obj;
1738 }
1739
1740 // Normal case where we just need to make a new object.
1741 obj = instantiateObject();
1742 mMap.put(name, obj);
1743 return obj;
1744 }
1745
1746 public T stopObject(String name) {
1747 T obj = mMap.get(name);
1748 if (obj != null) {
1749 return obj;
1750 }
1751
1752 // No object exists for the given name, but do we currently have it
1753 // running as part of the overflow?
1754 if (mActiveOverflow != null) {
1755 MutableInt over = mActiveOverflow.get(name);
1756 if (over != null) {
1757 // We are already actively counting this name in the overflow object.
1758 obj = mCurOverflow;
1759 if (obj != null) {
1760 over.value--;
1761 if (over.value <= 0) {
1762 mActiveOverflow.remove(name);
1763 }
1764 return obj;
1765 }
1766 }
1767 }
1768
1769 // Huh, they are stopping an active operation but we can't find one!
1770 // That's not good.
1771 Slog.wtf(TAG, "Unable to find object for " + name + " mapsize="
1772 + mMap.size() + " activeoverflow=" + mActiveOverflow
1773 + " curoverflow=" + mCurOverflow);
1774 return null;
1775 }
1776
1777 public abstract T instantiateObject();
1778 }
1779
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001780 /*
1781 * Get the wakeup reason counter, and create a new one if one
1782 * doesn't already exist.
1783 */
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001784 public SamplingTimer getWakeupReasonTimerLocked(String name) {
1785 SamplingTimer timer = mWakeupReasonStats.get(name);
1786 if (timer == null) {
1787 timer = new SamplingTimer(mOnBatteryTimeBase, true);
1788 mWakeupReasonStats.put(name, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001789 }
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001790 return timer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001791 }
1792
Evan Millarc64edde2009-04-18 12:26:32 -07001793 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001794 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001795 * doesn't already exist.
1796 */
1797 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1798 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1799 if (kwlt == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001800 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, true /* track reported values */);
Evan Millarc64edde2009-04-18 12:26:32 -07001801 mKernelWakelockStats.put(name, kwlt);
1802 }
1803 return kwlt;
1804 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001805
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001806 private int getCurrentBluetoothPingCount() {
1807 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001808 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1809 if (deviceList.size() > 0) {
1810 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001811 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001812 }
1813 return -1;
1814 }
1815
1816 public int getBluetoothPingCount() {
1817 if (mBluetoothPingStart == -1) {
1818 return mBluetoothPingCount;
1819 } else if (mBtHeadset != null) {
1820 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1821 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001822 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001823 }
1824
1825 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001826 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1827 mBluetoothPingStart = getCurrentBluetoothPingCount();
1828 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001829 mBtHeadset = headset;
1830 }
1831
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001832 private int writeHistoryTag(HistoryTag tag) {
1833 Integer idxObj = mHistoryTagPool.get(tag);
1834 int idx;
1835 if (idxObj != null) {
1836 idx = idxObj;
1837 } else {
1838 idx = mNextHistoryTagIdx;
1839 HistoryTag key = new HistoryTag();
1840 key.setTo(tag);
1841 tag.poolIdx = idx;
1842 mHistoryTagPool.put(key, idx);
1843 mNextHistoryTagIdx++;
1844 mNumHistoryTagChars += key.string.length() + 1;
1845 }
1846 return idx;
1847 }
1848
1849 private void readHistoryTag(int index, HistoryTag tag) {
1850 tag.string = mReadHistoryStrings[index];
1851 tag.uid = mReadHistoryUids[index];
1852 tag.poolIdx = index;
1853 }
1854
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001855 // Part of initial delta int that specifies the time delta.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001856 static final int DELTA_TIME_MASK = 0x7ffff;
1857 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
1858 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
1859 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001860 // Flag in delta int: a new battery level int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001861 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001862 // Flag in delta int: a new full state and battery status int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001863 static final int DELTA_STATE_FLAG = 0x00100000;
1864 // Flag in delta int: a new full state2 int follows.
1865 static final int DELTA_STATE2_FLAG = 0x00200000;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001866 // Flag in delta int: contains a wakelock or wakeReason tag.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001867 static final int DELTA_WAKELOCK_FLAG = 0x00400000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001868 // Flag in delta int: contains an event description.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001869 static final int DELTA_EVENT_FLAG = 0x00800000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001870 // These upper bits are the frequently changing state bits.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001871 static final int DELTA_STATE_MASK = 0xff000000;
1872
1873 // These are the pieces of battery state that are packed in to the upper bits of
1874 // the state int that have been packed in to the first delta int. They must fit
1875 // in DELTA_STATE_MASK.
1876 static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
1877 static final int STATE_BATTERY_STATUS_SHIFT = 29;
1878 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
1879 static final int STATE_BATTERY_HEALTH_SHIFT = 26;
1880 static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
1881 static final int STATE_BATTERY_PLUG_SHIFT = 24;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001882
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001883 // We use the low bit of the battery state int to indicate that we have full details
1884 // from a battery level change.
1885 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001;
1886
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001887 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001888 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001889 dest.writeInt(DELTA_TIME_ABS);
1890 cur.writeToParcel(dest, 0);
1891 return;
1892 }
1893
1894 final long deltaTime = cur.time - last.time;
1895 final int lastBatteryLevelInt = buildBatteryLevelInt(last);
1896 final int lastStateInt = buildStateInt(last);
1897
1898 int deltaTimeToken;
1899 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
1900 deltaTimeToken = DELTA_TIME_LONG;
1901 } else if (deltaTime >= DELTA_TIME_ABS) {
1902 deltaTimeToken = DELTA_TIME_INT;
1903 } else {
1904 deltaTimeToken = (int)deltaTime;
1905 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001906 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001907 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel
1908 ? BATTERY_DELTA_LEVEL_FLAG : 0;
1909 final boolean computeStepDetails = includeStepDetails != 0
1910 || mLastHistoryStepDetails == null;
1911 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001912 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
1913 if (batteryLevelIntChanged) {
1914 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
1915 }
1916 final int stateInt = buildStateInt(cur);
1917 final boolean stateIntChanged = stateInt != lastStateInt;
1918 if (stateIntChanged) {
1919 firstToken |= DELTA_STATE_FLAG;
1920 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001921 final boolean state2IntChanged = cur.states2 != last.states2;
1922 if (state2IntChanged) {
1923 firstToken |= DELTA_STATE2_FLAG;
1924 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001925 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001926 firstToken |= DELTA_WAKELOCK_FLAG;
1927 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001928 if (cur.eventCode != HistoryItem.EVENT_NONE) {
1929 firstToken |= DELTA_EVENT_FLAG;
1930 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001931 dest.writeInt(firstToken);
1932 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
1933 + " deltaTime=" + deltaTime);
1934
1935 if (deltaTimeToken >= DELTA_TIME_INT) {
1936 if (deltaTimeToken == DELTA_TIME_INT) {
1937 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
1938 dest.writeInt((int)deltaTime);
1939 } else {
1940 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
1941 dest.writeLong(deltaTime);
1942 }
1943 }
1944 if (batteryLevelIntChanged) {
1945 dest.writeInt(batteryLevelInt);
1946 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
1947 + Integer.toHexString(batteryLevelInt)
1948 + " batteryLevel=" + cur.batteryLevel
1949 + " batteryTemp=" + cur.batteryTemperature
1950 + " batteryVolt=" + (int)cur.batteryVoltage);
1951 }
1952 if (stateIntChanged) {
1953 dest.writeInt(stateInt);
1954 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
1955 + Integer.toHexString(stateInt)
1956 + " batteryStatus=" + cur.batteryStatus
1957 + " batteryHealth=" + cur.batteryHealth
1958 + " batteryPlugType=" + cur.batteryPlugType
1959 + " states=0x" + Integer.toHexString(cur.states));
1960 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001961 if (state2IntChanged) {
1962 dest.writeInt(cur.states2);
1963 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
1964 + Integer.toHexString(cur.states2));
1965 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001966 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
1967 int wakeLockIndex;
1968 int wakeReasonIndex;
1969 if (cur.wakelockTag != null) {
1970 wakeLockIndex = writeHistoryTag(cur.wakelockTag);
1971 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
1972 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
1973 } else {
1974 wakeLockIndex = 0xffff;
1975 }
1976 if (cur.wakeReasonTag != null) {
1977 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
1978 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
1979 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
1980 } else {
1981 wakeReasonIndex = 0xffff;
1982 }
1983 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001984 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001985 if (cur.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001986 int index = writeHistoryTag(cur.eventTag);
1987 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
Dianne Hackborn099bc622014-01-22 13:39:16 -08001988 dest.writeInt(codeAndIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001989 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
1990 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
1991 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001992 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001993 if (computeStepDetails) {
1994 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
1995 if (includeStepDetails != 0) {
1996 mCurHistoryStepDetails.writeToParcel(dest);
1997 }
1998 cur.stepDetails = mCurHistoryStepDetails;
1999 mLastHistoryStepDetails = mCurHistoryStepDetails;
2000 } else {
2001 cur.stepDetails = null;
2002 }
2003 if (mLastHistoryStepLevel < cur.batteryLevel) {
2004 mLastHistoryStepDetails = null;
2005 }
2006 mLastHistoryStepLevel = cur.batteryLevel;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002007 }
2008
2009 private int buildBatteryLevelInt(HistoryItem h) {
2010 return ((((int)h.batteryLevel)<<25)&0xfe000000)
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002011 | ((((int)h.batteryTemperature)<<14)&0x01ff8000)
2012 | ((((int)h.batteryVoltage)<<1)&0x00007fff);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002013 }
2014
2015 private int buildStateInt(HistoryItem h) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002016 int plugType = 0;
2017 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
2018 plugType = 1;
2019 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
2020 plugType = 2;
2021 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
2022 plugType = 3;
2023 }
2024 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
2025 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
2026 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002027 | (h.states&(~DELTA_STATE_MASK));
2028 }
2029
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002030 private void computeHistoryStepDetails(final HistoryStepDetails out,
2031 final HistoryStepDetails last) {
2032 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out;
2033
2034 // Perform a CPU update right after we do this collection, so we have started
2035 // collecting good data for the next step.
2036 requestImmediateCpuUpdate();
2037
2038 if (last == null) {
2039 // We are not generating a delta, so all we need to do is reset the stats
2040 // we will later be doing a delta from.
2041 final int NU = mUidStats.size();
2042 for (int i=0; i<NU; i++) {
2043 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
2044 uid.mLastStepUserTime = uid.mCurStepUserTime;
2045 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
2046 }
2047 mLastStepCpuUserTime = mCurStepCpuUserTime;
2048 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
2049 mLastStepStatUserTime = mCurStepStatUserTime;
2050 mLastStepStatSystemTime = mCurStepStatSystemTime;
2051 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
2052 mLastStepStatIrqTime = mCurStepStatIrqTime;
2053 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
2054 mLastStepStatIdleTime = mCurStepStatIdleTime;
2055 tmp.clear();
2056 return;
2057 }
2058 if (DEBUG) {
2059 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys="
2060 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime
2061 + " irq=" + mLastStepStatIrqTime + " sirq="
2062 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime);
2063 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys="
2064 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime
2065 + " irq=" + mCurStepStatIrqTime + " sirq="
2066 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime);
2067 }
2068 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime);
2069 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime);
2070 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime);
2071 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime);
2072 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime);
2073 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime);
2074 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime);
2075 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime);
2076 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1;
2077 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0;
2078 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0;
2079 final int NU = mUidStats.size();
2080 for (int i=0; i<NU; i++) {
2081 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
2082 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime);
2083 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime);
2084 final int totalTime = totalUTime + totalSTime;
2085 uid.mLastStepUserTime = uid.mCurStepUserTime;
2086 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
2087 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) {
2088 continue;
2089 }
2090 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) {
2091 out.appCpuUid3 = uid.mUid;
2092 out.appCpuUTime3 = totalUTime;
2093 out.appCpuSTime3 = totalSTime;
2094 } else {
2095 out.appCpuUid3 = out.appCpuUid2;
2096 out.appCpuUTime3 = out.appCpuUTime2;
2097 out.appCpuSTime3 = out.appCpuSTime2;
2098 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) {
2099 out.appCpuUid2 = uid.mUid;
2100 out.appCpuUTime2 = totalUTime;
2101 out.appCpuSTime2 = totalSTime;
2102 } else {
2103 out.appCpuUid2 = out.appCpuUid1;
2104 out.appCpuUTime2 = out.appCpuUTime1;
2105 out.appCpuSTime2 = out.appCpuSTime1;
2106 out.appCpuUid1 = uid.mUid;
2107 out.appCpuUTime1 = totalUTime;
2108 out.appCpuSTime1 = totalSTime;
2109 }
2110 }
2111 }
2112 mLastStepCpuUserTime = mCurStepCpuUserTime;
2113 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
2114 mLastStepStatUserTime = mCurStepStatUserTime;
2115 mLastStepStatSystemTime = mCurStepStatSystemTime;
2116 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
2117 mLastStepStatIrqTime = mCurStepStatIrqTime;
2118 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
2119 mLastStepStatIdleTime = mCurStepStatIdleTime;
2120 }
2121
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002122 public void readHistoryDelta(Parcel src, HistoryItem cur) {
2123 int firstToken = src.readInt();
2124 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002125 cur.cmd = HistoryItem.CMD_UPDATE;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002126 cur.numReadInts = 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002127 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
2128 + " deltaTimeToken=" + deltaTimeToken);
2129
2130 if (deltaTimeToken < DELTA_TIME_ABS) {
2131 cur.time += deltaTimeToken;
2132 } else if (deltaTimeToken == DELTA_TIME_ABS) {
2133 cur.time = src.readLong();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002134 cur.numReadInts += 2;
2135 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002136 cur.readFromParcel(src);
2137 return;
2138 } else if (deltaTimeToken == DELTA_TIME_INT) {
2139 int delta = src.readInt();
2140 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002141 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002142 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
2143 } else {
2144 long delta = src.readLong();
2145 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
2146 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002147 cur.numReadInts += 2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002148 }
2149
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002150 final int batteryLevelInt;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002151 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002152 batteryLevelInt = src.readInt();
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002153 cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
2154 cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21);
2155 cur.batteryVoltage = (char)(batteryLevelInt&0x3fff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002156 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002157 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
2158 + Integer.toHexString(batteryLevelInt)
2159 + " batteryLevel=" + cur.batteryLevel
2160 + " batteryTemp=" + cur.batteryTemperature
2161 + " batteryVolt=" + (int)cur.batteryVoltage);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002162 } else {
2163 batteryLevelInt = 0;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002164 }
2165
2166 if ((firstToken&DELTA_STATE_FLAG) != 0) {
2167 int stateInt = src.readInt();
2168 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002169 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
2170 & STATE_BATTERY_STATUS_MASK);
2171 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
2172 & STATE_BATTERY_HEALTH_MASK);
2173 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
2174 & STATE_BATTERY_PLUG_MASK);
2175 switch (cur.batteryPlugType) {
2176 case 1:
2177 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
2178 break;
2179 case 2:
2180 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
2181 break;
2182 case 3:
2183 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
2184 break;
2185 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002186 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002187 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
2188 + Integer.toHexString(stateInt)
2189 + " batteryStatus=" + cur.batteryStatus
2190 + " batteryHealth=" + cur.batteryHealth
2191 + " batteryPlugType=" + cur.batteryPlugType
2192 + " states=0x" + Integer.toHexString(cur.states));
2193 } else {
2194 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK));
2195 }
2196
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002197 if ((firstToken&DELTA_STATE2_FLAG) != 0) {
2198 cur.states2 = src.readInt();
2199 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
2200 + Integer.toHexString(cur.states2));
2201 }
2202
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002203 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002204 int indexes = src.readInt();
2205 int wakeLockIndex = indexes&0xffff;
2206 int wakeReasonIndex = (indexes>>16)&0xffff;
2207 if (wakeLockIndex != 0xffff) {
2208 cur.wakelockTag = cur.localWakelockTag;
2209 readHistoryTag(wakeLockIndex, cur.wakelockTag);
2210 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
2211 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
2212 } else {
2213 cur.wakelockTag = null;
2214 }
2215 if (wakeReasonIndex != 0xffff) {
2216 cur.wakeReasonTag = cur.localWakeReasonTag;
2217 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
2218 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
2219 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
2220 } else {
2221 cur.wakeReasonTag = null;
2222 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002223 cur.numReadInts += 1;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002224 } else {
2225 cur.wakelockTag = null;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002226 cur.wakeReasonTag = null;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002227 }
2228
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002229 if ((firstToken&DELTA_EVENT_FLAG) != 0) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002230 cur.eventTag = cur.localEventTag;
2231 final int codeAndIndex = src.readInt();
Dianne Hackborn099bc622014-01-22 13:39:16 -08002232 cur.eventCode = (codeAndIndex&0xffff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002233 final int index = ((codeAndIndex>>16)&0xffff);
2234 readHistoryTag(index, cur.eventTag);
2235 cur.numReadInts += 1;
2236 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
2237 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
2238 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002239 } else {
2240 cur.eventCode = HistoryItem.EVENT_NONE;
2241 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002242
2243 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) {
2244 cur.stepDetails = mReadHistoryStepDetails;
2245 cur.stepDetails.readFromParcel(src);
2246 } else {
2247 cur.stepDetails = null;
2248 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002249 }
2250
Dianne Hackbornfc064132014-06-02 12:42:12 -07002251 @Override
2252 public void commitCurrentHistoryBatchLocked() {
2253 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
2254 }
2255
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002256 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002257 if (!mHaveBatteryLevel || !mRecordingHistory) {
2258 return;
2259 }
2260
Dianne Hackborn40c87252014-03-19 16:55:40 -07002261 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002262 final int diffStates = mHistoryLastWritten.states^cur.states;
2263 final int diffStates2 = mHistoryLastWritten.states2^cur.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002264 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002265 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002266 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
2267 + Integer.toHexString(diffStates) + " lastDiff="
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002268 + Integer.toHexString(lastDiffStates) + " diff2="
2269 + Integer.toHexString(diffStates2) + " lastDiff2="
2270 + Integer.toHexString(lastDiffStates2));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002271 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002272 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002273 && (diffStates2&lastDiffStates2) == 0
2274 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
2275 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002276 && mHistoryLastWritten.stepDetails == null
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002277 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002278 || cur.eventCode == HistoryItem.EVENT_NONE)
2279 && mHistoryLastWritten.batteryLevel == cur.batteryLevel
2280 && mHistoryLastWritten.batteryStatus == cur.batteryStatus
2281 && mHistoryLastWritten.batteryHealth == cur.batteryHealth
2282 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
2283 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
2284 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002285 // We can merge this new change in with the last one. Merging is
Dianne Hackborn40c87252014-03-19 16:55:40 -07002286 // allowed as long as only the states have changed, and within those states
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002287 // as long as no bit has changed both between now and the last entry, as
2288 // well as the last entry and the one before it (so we capture any toggles).
2289 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002290 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
2291 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
2292 mHistoryBufferLastPos = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002293 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002294 // If the last written history had a wakelock tag, we need to retain it.
2295 // Note that the condition above made sure that we aren't in a case where
2296 // both it and the current history item have a wakelock tag.
2297 if (mHistoryLastWritten.wakelockTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002298 cur.wakelockTag = cur.localWakelockTag;
2299 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002300 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002301 // If the last written history had a wake reason tag, we need to retain it.
2302 // Note that the condition above made sure that we aren't in a case where
2303 // both it and the current history item have a wakelock tag.
2304 if (mHistoryLastWritten.wakeReasonTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002305 cur.wakeReasonTag = cur.localWakeReasonTag;
2306 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002307 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002308 // If the last written history had an event, we need to retain it.
2309 // Note that the condition above made sure that we aren't in a case where
2310 // both it and the current history item have an event.
2311 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002312 cur.eventCode = mHistoryLastWritten.eventCode;
2313 cur.eventTag = cur.localEventTag;
2314 cur.eventTag.setTo(mHistoryLastWritten.eventTag);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002315 }
Dianne Hackborn1fadab52011-04-14 17:57:33 -07002316 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002317 }
2318
2319 final int dataSize = mHistoryBuffer.dataSize();
2320 if (dataSize >= MAX_HISTORY_BUFFER) {
2321 if (!mHistoryOverflow) {
2322 mHistoryOverflow = true;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002323 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
2324 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002325 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002326 }
2327
2328 // Once we've reached the maximum number of items, we only
2329 // record changes to the battery level and the most interesting states.
2330 // Once we've reached the maximum maximum number of items, we only
2331 // record changes to the battery level.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002332 if (mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002333 (dataSize >= MAX_MAX_HISTORY_BUFFER
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002334 || ((mHistoryLastWritten.states^cur.states)
Dianne Hackborn3251b902014-06-20 14:40:53 -07002335 & HistoryItem.MOST_INTERESTING_STATES) == 0
2336 || ((mHistoryLastWritten.states2^cur.states2)
2337 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002338 return;
2339 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002340
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002341 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002342 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002343 }
2344
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002345 if (dataSize == 0) {
2346 // The history is currently empty; we need it to start with a time stamp.
2347 cur.currentTime = System.currentTimeMillis();
Dianne Hackborna7d0d552014-09-12 17:15:52 -07002348 mLastRecordedClockTime = cur.currentTime;
2349 mLastRecordedClockRealtime = elapsedRealtimeMs;
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002350 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur);
2351 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002352 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002353 }
2354
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002355 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
2356 HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002357 if (mIteratingHistory) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002358 throw new IllegalStateException("Can't do this while iterating history!");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002359 }
2360 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
2361 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002362 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002363 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07002364 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002365 cur.wakelockTag = null;
2366 cur.wakeReasonTag = null;
2367 cur.eventCode = HistoryItem.EVENT_NONE;
2368 cur.eventTag = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002369 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
2370 + " now " + mHistoryBuffer.dataPosition()
2371 + " size is now " + mHistoryBuffer.dataSize());
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002372 }
2373
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002374 int mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002375 int mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002376
Dianne Hackborn40c87252014-03-19 16:55:40 -07002377 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002378 if (mTrackRunningHistoryElapsedRealtime != 0) {
2379 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
2380 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
2381 if (diffUptime < (diffElapsed-20)) {
2382 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
2383 mHistoryAddTmp.setTo(mHistoryLastWritten);
2384 mHistoryAddTmp.wakelockTag = null;
2385 mHistoryAddTmp.wakeReasonTag = null;
2386 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
2387 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
2388 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
2389 }
2390 }
2391 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
2392 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
2393 mTrackRunningHistoryUptime = uptimeMs;
2394 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
2395 }
2396
2397 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
2398 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002399
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002400 if (!USE_OLD_HISTORY) {
2401 return;
2402 }
2403
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002404 if (!mHaveBatteryLevel || !mRecordingHistory) {
2405 return;
2406 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002407
2408 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002409 // and no states have since the last recorded entry changed and
2410 // are now resetting back to their original value, then just collapse
2411 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002412 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002413 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002414 && ((mHistoryEnd.states^cur.states)&mChangedStates) == 0
2415 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002416 // If the current is the same as the one before, then we no
2417 // longer need the entry.
2418 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002419 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002420 && mHistoryLastEnd.sameNonEvent(cur)) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002421 mHistoryLastEnd.next = null;
2422 mHistoryEnd.next = mHistoryCache;
2423 mHistoryCache = mHistoryEnd;
2424 mHistoryEnd = mHistoryLastEnd;
2425 mHistoryLastEnd = null;
2426 } else {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002427 mChangedStates |= mHistoryEnd.states^cur.states;
2428 mChangedStates2 |= mHistoryEnd.states^cur.states2;
2429 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002430 }
2431 return;
2432 }
2433
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002434 mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002435 mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002436
2437 if (mNumHistoryItems == MAX_HISTORY_ITEMS
2438 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002439 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002440 }
2441
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002442 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
2443 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002444 // record changes to the battery level and the most interesting states.
2445 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002446 // record changes to the battery level.
2447 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002448 == cur.batteryLevel &&
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002449 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002450 || ((mHistoryEnd.states^cur.states)
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002451 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002452 return;
2453 }
2454 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002455
Dianne Hackborn40c87252014-03-19 16:55:40 -07002456 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002457 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002458
Dianne Hackborn40c87252014-03-19 16:55:40 -07002459 void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
2460 String name, int uid) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002461 mHistoryCur.eventCode = code;
2462 mHistoryCur.eventTag = mHistoryCur.localEventTag;
2463 mHistoryCur.eventTag.string = name;
2464 mHistoryCur.eventTag.uid = uid;
Dianne Hackborn4590e522014-03-24 13:36:46 -07002465 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002466 }
2467
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002468 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002469 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002470 if (rec != null) {
2471 mHistoryCache = rec.next;
2472 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002473 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002474 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002475 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002476
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002477 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002478 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002479
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002480 void addHistoryRecordLocked(HistoryItem rec) {
2481 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002482 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002483 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002484 if (mHistoryEnd != null) {
2485 mHistoryEnd.next = rec;
2486 mHistoryEnd = rec;
2487 } else {
2488 mHistory = mHistoryEnd = rec;
2489 }
2490 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002491
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002492 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002493 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002494 if (USE_OLD_HISTORY) {
2495 if (mHistory != null) {
2496 mHistoryEnd.next = mHistoryCache;
2497 mHistoryCache = mHistory;
2498 mHistory = mHistoryLastEnd = mHistoryEnd = null;
2499 }
2500 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002501 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002502
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002503 mHistoryBaseTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002504 mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002505 mTrackRunningHistoryElapsedRealtime = 0;
2506 mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002507
2508 mHistoryBuffer.setDataSize(0);
2509 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002510 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002511 mHistoryLastLastWritten.clear();
2512 mHistoryLastWritten.clear();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002513 mHistoryTagPool.clear();
2514 mNextHistoryTagIdx = 0;
2515 mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002516 mHistoryBufferLastPos = -1;
2517 mHistoryOverflow = false;
Dianne Hackborna7d0d552014-09-12 17:15:52 -07002518 mLastRecordedClockTime = 0;
2519 mLastRecordedClockRealtime = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002520 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002521
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002522 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
2523 long realtime) {
2524 if (mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime)) {
2525 if (unplugged) {
2526 // Track bt headset ping count
2527 mBluetoothPingStart = getCurrentBluetoothPingCount();
2528 mBluetoothPingCount = 0;
2529 } else {
2530 // Track bt headset ping count
2531 mBluetoothPingCount = getBluetoothPingCount();
2532 mBluetoothPingStart = -1;
2533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002535
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002536 boolean unpluggedScreenOff = unplugged && screenOff;
2537 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
2538 updateKernelWakelocksLocked();
2539 requestWakelockCpuUpdate();
2540 if (!unpluggedScreenOff) {
2541 // We are switching to no longer tracking wake locks, but we want
2542 // the next CPU update we receive to take them in to account.
2543 mDistributeWakelockCpu = true;
2544 }
2545 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002546 }
2547 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002548
Dianne Hackborn099bc622014-01-22 13:39:16 -08002549 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
2550 mIsolatedUids.put(isolatedUid, appUid);
2551 }
2552
2553 public void removeIsolatedUidLocked(int isolatedUid, int appUid) {
2554 int curUid = mIsolatedUids.get(isolatedUid, -1);
2555 if (curUid == appUid) {
2556 mIsolatedUids.delete(isolatedUid);
2557 }
2558 }
2559
2560 public int mapUid(int uid) {
2561 int isolated = mIsolatedUids.get(uid, -1);
2562 return isolated > 0 ? isolated : uid;
2563 }
2564
2565 public void noteEventLocked(int code, String name, int uid) {
2566 uid = mapUid(uid);
Dianne Hackborn37de0982014-05-09 09:32:18 -07002567 if (!mActiveEvents.updateState(code, name, uid, 0)) {
2568 return;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002569 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07002570 final long elapsedRealtime = SystemClock.elapsedRealtime();
2571 final long uptime = SystemClock.uptimeMillis();
2572 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002573 }
2574
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07002575 public void noteCurrentTimeChangedLocked() {
2576 final long currentTime = System.currentTimeMillis();
2577 final long elapsedRealtime = SystemClock.elapsedRealtime();
2578 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborna7d0d552014-09-12 17:15:52 -07002579 if (isStartClockTimeValid()) {
2580 // Has the time changed sufficiently that it is really worth recording?
2581 if (mLastRecordedClockTime != 0) {
2582 long expectedClockTime = mLastRecordedClockTime
2583 + (elapsedRealtime - mLastRecordedClockRealtime);
2584 if (currentTime >= (expectedClockTime-500)
2585 && currentTime <= (expectedClockTime+500)) {
2586 // Not sufficiently changed, skip!
2587 return;
2588 }
2589 }
2590 }
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07002591 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
2592 if (isStartClockTimeValid()) {
2593 mStartClockTime = currentTime;
2594 }
2595 }
2596
Dianne Hackborn61659e52014-07-09 16:13:01 -07002597 public void noteProcessStartLocked(String name, int uid) {
2598 uid = mapUid(uid);
2599 if (isOnBattery()) {
2600 Uid u = getUidStatsLocked(uid);
2601 u.getProcessStatsLocked(name).incStartsLocked();
2602 }
2603 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) {
2604 return;
2605 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002606 if (!mRecordAllHistory) {
2607 return;
2608 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07002609 final long elapsedRealtime = SystemClock.elapsedRealtime();
2610 final long uptime = SystemClock.uptimeMillis();
2611 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid);
2612 }
2613
Dianne Hackborn1e01d162014-12-04 17:46:42 -08002614 public void noteProcessCrashLocked(String name, int uid) {
2615 uid = mapUid(uid);
2616 if (isOnBattery()) {
2617 Uid u = getUidStatsLocked(uid);
2618 u.getProcessStatsLocked(name).incNumCrashesLocked();
2619 }
2620 }
2621
2622 public void noteProcessAnrLocked(String name, int uid) {
2623 uid = mapUid(uid);
2624 if (isOnBattery()) {
2625 Uid u = getUidStatsLocked(uid);
2626 u.getProcessStatsLocked(name).incNumAnrsLocked();
2627 }
2628 }
2629
Dianne Hackborn61659e52014-07-09 16:13:01 -07002630 public void noteProcessStateLocked(String name, int uid, int state) {
2631 uid = mapUid(uid);
2632 final long elapsedRealtime = SystemClock.elapsedRealtime();
2633 getUidStatsLocked(uid).updateProcessStateLocked(name, state, elapsedRealtime);
2634 }
2635
2636 public void noteProcessFinishLocked(String name, int uid) {
2637 uid = mapUid(uid);
2638 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) {
2639 return;
2640 }
2641 final long elapsedRealtime = SystemClock.elapsedRealtime();
2642 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn61659e52014-07-09 16:13:01 -07002643 getUidStatsLocked(uid).updateProcessStateLocked(name, Uid.PROCESS_STATE_NONE,
2644 elapsedRealtime);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002645 if (!mRecordAllHistory) {
2646 return;
2647 }
2648 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid);
Dianne Hackborn61659e52014-07-09 16:13:01 -07002649 }
2650
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002651 public void noteSyncStartLocked(String name, int uid) {
2652 uid = mapUid(uid);
2653 final long elapsedRealtime = SystemClock.elapsedRealtime();
2654 final long uptime = SystemClock.uptimeMillis();
2655 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime);
2656 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
2657 return;
2658 }
2659 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid);
2660 }
2661
2662 public void noteSyncFinishLocked(String name, int uid) {
2663 uid = mapUid(uid);
2664 final long elapsedRealtime = SystemClock.elapsedRealtime();
2665 final long uptime = SystemClock.uptimeMillis();
2666 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime);
2667 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
2668 return;
2669 }
2670 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid);
2671 }
2672
2673 public void noteJobStartLocked(String name, int uid) {
2674 uid = mapUid(uid);
2675 final long elapsedRealtime = SystemClock.elapsedRealtime();
2676 final long uptime = SystemClock.uptimeMillis();
2677 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime);
2678 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
2679 return;
2680 }
2681 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid);
2682 }
2683
2684 public void noteJobFinishLocked(String name, int uid) {
2685 uid = mapUid(uid);
2686 final long elapsedRealtime = SystemClock.elapsedRealtime();
2687 final long uptime = SystemClock.uptimeMillis();
2688 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime);
2689 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
2690 return;
2691 }
2692 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid);
2693 }
2694
Dianne Hackborn1e383822015-04-10 14:02:33 -07002695 public void noteAlarmStartLocked(String name, int uid) {
2696 if (!mRecordAllHistory) {
2697 return;
2698 }
2699 uid = mapUid(uid);
2700 final long elapsedRealtime = SystemClock.elapsedRealtime();
2701 final long uptime = SystemClock.uptimeMillis();
2702 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_START, name, uid, 0)) {
2703 return;
2704 }
2705 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid);
2706 }
2707
2708 public void noteAlarmFinishLocked(String name, int uid) {
2709 if (!mRecordAllHistory) {
2710 return;
2711 }
2712 uid = mapUid(uid);
2713 final long elapsedRealtime = SystemClock.elapsedRealtime();
2714 final long uptime = SystemClock.uptimeMillis();
2715 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) {
2716 return;
2717 }
2718 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid);
2719 }
2720
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002721 private void requestWakelockCpuUpdate() {
2722 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
2723 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
2724 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
2725 }
2726 }
2727
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002728 private void requestImmediateCpuUpdate() {
2729 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2730 mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS);
2731 }
2732
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002733 public void setRecordAllHistoryLocked(boolean enabled) {
2734 mRecordAllHistory = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002735 if (!enabled) {
2736 // Clear out any existing state.
2737 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK);
Dianne Hackborn1e383822015-04-10 14:02:33 -07002738 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002739 // Record the currently running processes as stopping, now that we are no
2740 // longer tracking them.
2741 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
2742 HistoryItem.EVENT_PROC);
2743 if (active != null) {
2744 long mSecRealtime = SystemClock.elapsedRealtime();
2745 final long mSecUptime = SystemClock.uptimeMillis();
2746 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
2747 SparseIntArray uids = ent.getValue();
2748 for (int j=0; j<uids.size(); j++) {
2749 addHistoryEventLocked(mSecRealtime, mSecUptime,
2750 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j));
2751 }
2752 }
2753 }
2754 } else {
2755 // Record the currently running processes as starting, now that we are tracking them.
2756 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
2757 HistoryItem.EVENT_PROC);
2758 if (active != null) {
2759 long mSecRealtime = SystemClock.elapsedRealtime();
2760 final long mSecUptime = SystemClock.uptimeMillis();
2761 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
2762 SparseIntArray uids = ent.getValue();
2763 for (int j=0; j<uids.size(); j++) {
2764 addHistoryEventLocked(mSecRealtime, mSecUptime,
2765 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j));
2766 }
2767 }
2768 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002769 }
2770 }
2771
Dianne Hackborn9a755432014-05-15 17:05:22 -07002772 public void setNoAutoReset(boolean enabled) {
2773 mNoAutoReset = enabled;
2774 }
2775
2776 private String mInitialAcquireWakeName;
2777 private int mInitialAcquireWakeUid = -1;
2778
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002779 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002780 boolean unimportantForLogging, long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002781 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002782 if (type == WAKE_TYPE_PARTIAL) {
2783 // Only care about partial wake locks, since full wake locks
2784 // will be canceled when the user puts the screen to sleep.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002785 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002786 if (historyName == null) {
2787 historyName = name;
2788 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002789 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002790 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
2791 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002792 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002793 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002794 }
2795 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002796 if (mWakeLockNesting == 0) {
2797 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
2798 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
2799 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002800 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002801 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002802 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002803 mWakeLockImportant = !unimportantForLogging;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002804 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002805 } else if (!mWakeLockImportant && !unimportantForLogging
2806 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002807 if (mHistoryLastWritten.wakelockTag != null) {
2808 // We'll try to update the last tag.
2809 mHistoryLastWritten.wakelockTag = null;
2810 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002811 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002812 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002813 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002814 }
2815 mWakeLockImportant = true;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002816 }
2817 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002818 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002819 if (uid >= 0) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002820 //if (uid == 0) {
2821 // Slog.wtf(TAG, "Acquiring wake lock from root: " + name);
2822 //}
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002823 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002824 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002825 }
2826 }
2827
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002828 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type,
2829 long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002830 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002831 if (type == WAKE_TYPE_PARTIAL) {
2832 mWakeLockNesting--;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002833 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002834 if (historyName == null) {
2835 historyName = name;
2836 }
2837 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
2838 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002839 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002840 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002841 }
2842 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002843 if (mWakeLockNesting == 0) {
2844 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
2845 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
2846 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn37de0982014-05-09 09:32:18 -07002847 mInitialAcquireWakeName = null;
2848 mInitialAcquireWakeUid = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002849 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002850 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002851 }
2852 if (uid >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002853 requestWakelockCpuUpdate();
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
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002922 public int startAddingCpuLocked() {
2923 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2924
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002925 if (!mOnBatteryInternal) {
2926 return -1;
2927 }
2928
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002929 final int N = mPartialTimers.size();
2930 if (N == 0) {
2931 mLastPartialTimers.clear();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002932 mDistributeWakelockCpu = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002933 return 0;
2934 }
2935
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002936 if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) {
2937 return 0;
2938 }
2939
2940 mDistributeWakelockCpu = false;
2941
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002942 // How many timers should consume CPU? Only want to include ones
2943 // that have already been in the list.
2944 for (int i=0; i<N; i++) {
2945 StopwatchTimer st = mPartialTimers.get(i);
2946 if (st.mInList) {
2947 Uid uid = st.mUid;
2948 // We don't include the system UID, because it so often
2949 // holds wake locks at one request or another of an app.
2950 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2951 return 50;
2952 }
2953 }
2954 }
2955
2956 return 0;
2957 }
2958
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002959 public void finishAddingCpuLocked(int perc, int remainUTime, int remainSTtime,
2960 int totalUTime, int totalSTime, int statUserTime, int statSystemTime,
2961 int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime,
2962 long[] cpuSpeedTimes) {
2963 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
2964 + " user=" + statUserTime + " sys=" + statSystemTime
2965 + " io=" + statIOWaitTime + " irq=" + statIrqTime
2966 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime);
2967 mCurStepCpuUserTime += totalUTime;
2968 mCurStepCpuSystemTime += totalSTime;
2969 mCurStepStatUserTime += statUserTime;
2970 mCurStepStatSystemTime += statSystemTime;
2971 mCurStepStatIOWaitTime += statIOWaitTime;
2972 mCurStepStatIrqTime += statIrqTime;
2973 mCurStepStatSoftIrqTime += statSoftIrqTime;
2974 mCurStepStatIdleTime += statIdleTime;
2975
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002976 final int N = mPartialTimers.size();
2977 if (perc != 0) {
2978 int num = 0;
2979 for (int i=0; i<N; i++) {
2980 StopwatchTimer st = mPartialTimers.get(i);
2981 if (st.mInList) {
2982 Uid uid = st.mUid;
2983 // We don't include the system UID, because it so often
2984 // holds wake locks at one request or another of an app.
2985 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2986 num++;
2987 }
2988 }
2989 }
2990 if (num != 0) {
2991 for (int i=0; i<N; i++) {
2992 StopwatchTimer st = mPartialTimers.get(i);
2993 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002994 Uid uid = st.mUid;
2995 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002996 int myUTime = remainUTime/num;
2997 int mySTime = remainSTtime/num;
2998 remainUTime -= myUTime;
2999 remainSTtime -= mySTime;
Dianne Hackborn618b8c12010-09-09 23:10:38 -07003000 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003001 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003002 proc.addCpuTimeLocked(myUTime, mySTime, cpuSpeedTimes);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003003 }
3004 }
3005 }
3006 }
3007
3008 // Just in case, collect any lost CPU time.
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003009 if (remainUTime != 0 || remainSTtime != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003010 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
3011 if (uid != null) {
3012 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003013 proc.addCpuTimeLocked(remainUTime, remainSTtime, cpuSpeedTimes);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003014 }
3015 }
3016 }
3017
3018 final int NL = mLastPartialTimers.size();
3019 boolean diff = N != NL;
3020 for (int i=0; i<NL && !diff; i++) {
3021 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
3022 }
3023 if (!diff) {
3024 for (int i=0; i<NL; i++) {
3025 mPartialTimers.get(i).mInList = true;
3026 }
3027 return;
3028 }
3029
3030 for (int i=0; i<NL; i++) {
3031 mLastPartialTimers.get(i).mInList = false;
3032 }
3033 mLastPartialTimers.clear();
3034 for (int i=0; i<N; i++) {
3035 StopwatchTimer st = mPartialTimers.get(i);
3036 st.mInList = true;
3037 mLastPartialTimers.add(st);
3038 }
3039 }
3040
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003041 public void noteProcessDiedLocked(int uid, int pid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003042 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003043 Uid u = mUidStats.get(uid);
3044 if (u != null) {
3045 u.mPids.remove(pid);
3046 }
3047 }
3048
3049 public long getProcessWakeTime(int uid, int pid, long realtime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003050 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003051 Uid u = mUidStats.get(uid);
3052 if (u != null) {
3053 Uid.Pid p = u.mPids.get(pid);
3054 if (p != null) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003055 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003056 }
3057 }
3058 return 0;
3059 }
3060
3061 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003062 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003063 Uid u = mUidStats.get(uid);
3064 if (u != null) {
3065 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
3066 }
3067 }
3068
Dianne Hackborn287952c2010-09-22 22:34:31 -07003069 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003070 uid = mapUid(uid);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003071 Uid u = mUidStats.get(uid);
3072 if (u != null) {
3073 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
3074 }
3075 }
3076
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003077 int mSensorNesting;
3078
3079 public void noteStartSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003080 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003081 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003082 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003083 if (mSensorNesting == 0) {
3084 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
3085 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
3086 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003087 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003088 }
3089 mSensorNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003090 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003091 }
3092
3093 public void noteStopSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003094 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003095 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003096 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003097 mSensorNesting--;
3098 if (mSensorNesting == 0) {
3099 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
3100 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
3101 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003102 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003103 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003104 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003105 }
3106
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003107 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003108
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003109 public void noteStartGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003110 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003111 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003112 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003113 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003114 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003115 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
3116 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003117 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003118 }
3119 mGpsNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003120 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003121 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003122
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003123 public void noteStopGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003124 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003125 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003126 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003127 mGpsNesting--;
3128 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003129 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003130 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
3131 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003132 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003133 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003134 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003135 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003136
Jeff Browne95c3cd2014-05-02 16:59:26 -07003137 public void noteScreenStateLocked(int state) {
3138 if (mScreenState != state) {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08003139 recordDailyStatsIfNeededLocked(true);
Jeff Browne95c3cd2014-05-02 16:59:26 -07003140 final int oldState = mScreenState;
3141 mScreenState = state;
3142 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
3143 + ", newState=" + Display.stateToString(state));
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003144
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003145 if (state != Display.STATE_UNKNOWN) {
3146 int stepState = state-1;
3147 if (stepState < 4) {
3148 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState;
3149 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_SCREEN_STATE) | stepState;
3150 } else {
3151 Slog.wtf(TAG, "Unexpected screen state: " + state);
3152 }
3153 }
3154
Jeff Browne95c3cd2014-05-02 16:59:26 -07003155 if (state == Display.STATE_ON) {
3156 // Screen turning on.
3157 final long elapsedRealtime = SystemClock.elapsedRealtime();
3158 final long uptime = SystemClock.uptimeMillis();
3159 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
3160 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
3161 + Integer.toHexString(mHistoryCur.states));
3162 addHistoryRecordLocked(elapsedRealtime, uptime);
3163 mScreenOnTimer.startRunningLocked(elapsedRealtime);
3164 if (mScreenBrightnessBin >= 0) {
3165 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
3166 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003167
Jeff Browne95c3cd2014-05-02 16:59:26 -07003168 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false,
3169 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003170
Jeff Browne95c3cd2014-05-02 16:59:26 -07003171 // Fake a wake lock, so we consider the device waked as long
3172 // as the screen is on.
3173 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
3174 elapsedRealtime, uptime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003175
Jeff Browne95c3cd2014-05-02 16:59:26 -07003176 // Update discharge amounts.
3177 if (mOnBatteryInternal) {
3178 updateDischargeScreenLevelsLocked(false, true);
3179 }
3180 } else if (oldState == Display.STATE_ON) {
3181 // Screen turning off or dozing.
3182 final long elapsedRealtime = SystemClock.elapsedRealtime();
3183 final long uptime = SystemClock.uptimeMillis();
3184 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
3185 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
3186 + Integer.toHexString(mHistoryCur.states));
3187 addHistoryRecordLocked(elapsedRealtime, uptime);
3188 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
3189 if (mScreenBrightnessBin >= 0) {
3190 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
3191 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003192
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003193 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL,
Jeff Browne95c3cd2014-05-02 16:59:26 -07003194 elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003195
Jeff Browne95c3cd2014-05-02 16:59:26 -07003196 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
3197 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003198
Jeff Browne95c3cd2014-05-02 16:59:26 -07003199 // Update discharge amounts.
3200 if (mOnBatteryInternal) {
3201 updateDischargeScreenLevelsLocked(true, false);
3202 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08003203 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07003204 }
3205 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003206
Dianne Hackborn617f8772009-03-31 15:04:46 -07003207 public void noteScreenBrightnessLocked(int brightness) {
3208 // Bin the brightness.
3209 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
3210 if (bin < 0) bin = 0;
3211 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
3212 if (mScreenBrightnessBin != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003213 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003214 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003215 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
3216 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003217 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
3218 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003219 addHistoryRecordLocked(elapsedRealtime, uptime);
Jeff Browne95c3cd2014-05-02 16:59:26 -07003220 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003221 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003222 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003223 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003224 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003225 }
3226 mScreenBrightnessBin = bin;
3227 }
3228 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003229
Dianne Hackborn617f8772009-03-31 15:04:46 -07003230 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003231 if (mOnBatteryInternal) {
3232 uid = mapUid(uid);
3233 getUidStatsLocked(uid).noteUserActivityLocked(event);
3234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003235 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003236
Jeff Browne95c3cd2014-05-02 16:59:26 -07003237 public void noteInteractiveLocked(boolean interactive) {
3238 if (mInteractive != interactive) {
3239 final long elapsedRealtime = SystemClock.elapsedRealtime();
3240 mInteractive = interactive;
3241 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
3242 if (interactive) {
3243 mInteractiveTimer.startRunningLocked(elapsedRealtime);
3244 } else {
3245 mInteractiveTimer.stopRunningLocked(elapsedRealtime);
3246 }
3247 }
3248 }
3249
Dianne Hackborn1e01d162014-12-04 17:46:42 -08003250 public void noteConnectivityChangedLocked(int type, String extra) {
3251 final long elapsedRealtime = SystemClock.elapsedRealtime();
3252 final long uptime = SystemClock.uptimeMillis();
3253 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
3254 extra, type);
3255 mNumConnectivityChange++;
3256 }
3257
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003258 public void noteMobileRadioPowerState(int powerState, long timestampNs) {
3259 final long elapsedRealtime = SystemClock.elapsedRealtime();
3260 final long uptime = SystemClock.uptimeMillis();
3261 if (mMobileRadioPowerState != powerState) {
3262 long realElapsedRealtimeMs;
3263 final boolean active =
3264 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
3265 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
3266 if (active) {
Dianne Hackbornf7097a52014-05-13 09:56:14 -07003267 mMobileRadioActiveStartTime = realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003268 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
3269 } else {
3270 realElapsedRealtimeMs = timestampNs / (1000*1000);
Dianne Hackbornf7097a52014-05-13 09:56:14 -07003271 long lastUpdateTimeMs = mMobileRadioActiveStartTime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003272 if (realElapsedRealtimeMs < lastUpdateTimeMs) {
3273 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
3274 + " is before start time " + lastUpdateTimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003275 realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003276 } else if (realElapsedRealtimeMs < elapsedRealtime) {
3277 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
3278 - realElapsedRealtimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003279 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003280 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
3281 }
3282 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
3283 + Integer.toHexString(mHistoryCur.states));
3284 addHistoryRecordLocked(elapsedRealtime, uptime);
3285 mMobileRadioPowerState = powerState;
3286 if (active) {
3287 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
3288 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
3289 } else {
3290 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003291 updateMobileRadioStateLocked(realElapsedRealtimeMs);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003292 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003293 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003294 }
3295 }
3296
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003297 public void notePowerSaveMode(boolean enabled) {
3298 if (mPowerSaveModeEnabled != enabled) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003299 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0;
3300 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState;
3301 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003302 final long elapsedRealtime = SystemClock.elapsedRealtime();
3303 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003304 mPowerSaveModeEnabled = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003305 if (enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003306 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
3307 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003308 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003309 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003310 } else {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003311 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
3312 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003313 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003314 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003315 }
3316 addHistoryRecordLocked(elapsedRealtime, uptime);
3317 }
3318 }
3319
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003320 public void noteDeviceIdleModeLocked(boolean enabled, boolean fromActive, boolean fromMotion) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003321 final long elapsedRealtime = SystemClock.elapsedRealtime();
3322 final long uptime = SystemClock.uptimeMillis();
3323 boolean nowIdling = enabled;
3324 if (mDeviceIdling && !enabled && !fromActive && !fromMotion) {
3325 // We don't go out of general idling mode until explicitly taken out of
3326 // device idle through going active or significant motion.
3327 nowIdling = true;
3328 }
3329 if (mDeviceIdling != nowIdling) {
3330 mDeviceIdling = nowIdling;
3331 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0;
3332 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState;
3333 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState;
3334 if (enabled) {
3335 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime);
3336 } else {
3337 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime);
3338 }
3339 }
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003340 if (mDeviceIdleModeEnabled != enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003341 mDeviceIdleModeEnabled = enabled;
3342 if (fromMotion) {
3343 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SIGNIFICANT_MOTION,
3344 "", 0);
3345 }
3346 if (fromActive) {
3347 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
3348 "", 0);
3349 }
3350 if (enabled) {
3351 mHistoryCur.states2 |= HistoryItem.STATE2_DEVICE_IDLE_FLAG;
3352 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode enabled to: "
3353 + Integer.toHexString(mHistoryCur.states2));
3354 mDeviceIdleModeEnabledTimer.startRunningLocked(elapsedRealtime);
3355 } else {
3356 mHistoryCur.states2 &= ~HistoryItem.STATE2_DEVICE_IDLE_FLAG;
3357 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode disabled to: "
3358 + Integer.toHexString(mHistoryCur.states2));
3359 mDeviceIdleModeEnabledTimer.stopRunningLocked(elapsedRealtime);
3360 }
3361 addHistoryRecordLocked(elapsedRealtime, uptime);
3362 }
3363 }
3364
3365 public void notePackageInstalledLocked(String pkgName, int versionCode) {
3366 final long elapsedRealtime = SystemClock.elapsedRealtime();
3367 final long uptime = SystemClock.uptimeMillis();
3368 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED,
3369 pkgName, versionCode);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003370 PackageChange pc = new PackageChange();
3371 pc.mPackageName = pkgName;
3372 pc.mUpdate = true;
3373 pc.mVersionCode = versionCode;
3374 addPackageChange(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003375 }
3376
3377 public void notePackageUninstalledLocked(String pkgName) {
3378 final long elapsedRealtime = SystemClock.elapsedRealtime();
3379 final long uptime = SystemClock.uptimeMillis();
3380 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
3381 pkgName, 0);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003382 PackageChange pc = new PackageChange();
3383 pc.mPackageName = pkgName;
3384 pc.mUpdate = true;
3385 addPackageChange(pc);
3386 }
3387
3388 private void addPackageChange(PackageChange pc) {
3389 if (mDailyPackageChanges == null) {
3390 mDailyPackageChanges = new ArrayList<>();
3391 }
3392 mDailyPackageChanges.add(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003393 }
3394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003395 public void notePhoneOnLocked() {
3396 if (!mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003397 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003398 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003399 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003400 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
3401 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003402 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403 mPhoneOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003404 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 }
3406 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003408 public void notePhoneOffLocked() {
3409 if (mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003410 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003411 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003412 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003413 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
3414 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003415 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003416 mPhoneOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003417 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 }
3419 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003420
Dianne Hackborn3251b902014-06-20 14:40:53 -07003421 void stopAllPhoneSignalStrengthTimersLocked(int except) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003422 final long elapsedRealtime = SystemClock.elapsedRealtime();
Wink Saville52840902011-02-18 12:40:47 -08003423 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003424 if (i == except) {
3425 continue;
3426 }
3427 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003428 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003429 }
3430 }
3431 }
3432
Dianne Hackborne4a59512010-12-07 11:08:07 -08003433 private int fixPhoneServiceState(int state, int signalBin) {
3434 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
3435 // In this case we will always be STATE_OUT_OF_SERVICE, so need
3436 // to infer that we are scanning from other data.
3437 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08003438 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003439 state = ServiceState.STATE_IN_SERVICE;
3440 }
3441 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003442
Dianne Hackborne4a59512010-12-07 11:08:07 -08003443 return state;
3444 }
3445
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003446 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003447 boolean scanning = false;
3448 boolean newHistory = false;
3449
3450 mPhoneServiceStateRaw = state;
3451 mPhoneSimStateRaw = simState;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003452 mPhoneSignalStrengthBinRaw = strengthBin;
3453
3454 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003455 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne4a59512010-12-07 11:08:07 -08003456
3457 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
3458 // In this case we will always be STATE_OUT_OF_SERVICE, so need
3459 // to infer that we are scanning from other data.
3460 if (state == ServiceState.STATE_OUT_OF_SERVICE
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003461 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003462 state = ServiceState.STATE_IN_SERVICE;
3463 }
3464 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003465
3466 // If the phone is powered off, stop all timers.
3467 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003468 strengthBin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07003469
Dianne Hackborne4a59512010-12-07 11:08:07 -08003470 // If we are in service, make sure the correct signal string timer is running.
3471 } else if (state == ServiceState.STATE_IN_SERVICE) {
3472 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003473
3474 // If we're out of service, we are in the lowest signal strength
3475 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07003476 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003477 scanning = true;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003478 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07003479 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003480 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08003481 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003482 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
3483 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003484 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
Amith Yamasanif37447b2009-10-08 18:28:01 -07003485 }
3486 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003487
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003488 if (!scanning) {
3489 // If we are no longer scanning, then stop the scanning timer.
3490 if (mPhoneSignalScanningTimer.isRunningLocked()) {
3491 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
3492 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
3493 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08003494 newHistory = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003495 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003496 }
3497 }
3498
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003499 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003500 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
3501 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003502 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003503 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08003504 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003505 mPhoneServiceState = state;
3506 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08003507
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003508 if (mPhoneSignalStrengthBin != strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003509 if (mPhoneSignalStrengthBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003510 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003511 elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003512 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003513 if (strengthBin >= 0) {
3514 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003515 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003516 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07003517 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
3518 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003519 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
Dianne Hackborne4a59512010-12-07 11:08:07 -08003520 + Integer.toHexString(mHistoryCur.states));
3521 newHistory = true;
3522 } else {
Dianne Hackborn3251b902014-06-20 14:40:53 -07003523 stopAllPhoneSignalStrengthTimersLocked(-1);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003524 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003525 mPhoneSignalStrengthBin = strengthBin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08003526 }
3527
3528 if (newHistory) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07003529 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003530 }
3531 }
3532
3533 /**
3534 * Telephony stack updates the phone state.
3535 * @param state phone state from ServiceState.getState()
3536 */
3537 public void notePhoneStateLocked(int state, int simState) {
3538 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003539 }
3540
Wink Savillee9b06d72009-05-18 21:47:50 -07003541 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07003542 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08003543 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08003544 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003545 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003546
Dianne Hackborn627bba72009-03-24 22:32:56 -07003547 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
3548 int bin = DATA_CONNECTION_NONE;
3549 if (hasData) {
3550 switch (dataType) {
3551 case TelephonyManager.NETWORK_TYPE_EDGE:
3552 bin = DATA_CONNECTION_EDGE;
3553 break;
3554 case TelephonyManager.NETWORK_TYPE_GPRS:
3555 bin = DATA_CONNECTION_GPRS;
3556 break;
3557 case TelephonyManager.NETWORK_TYPE_UMTS:
3558 bin = DATA_CONNECTION_UMTS;
3559 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003560 case TelephonyManager.NETWORK_TYPE_CDMA:
3561 bin = DATA_CONNECTION_CDMA;
3562 break;
3563 case TelephonyManager.NETWORK_TYPE_EVDO_0:
3564 bin = DATA_CONNECTION_EVDO_0;
3565 break;
3566 case TelephonyManager.NETWORK_TYPE_EVDO_A:
3567 bin = DATA_CONNECTION_EVDO_A;
3568 break;
3569 case TelephonyManager.NETWORK_TYPE_1xRTT:
3570 bin = DATA_CONNECTION_1xRTT;
3571 break;
3572 case TelephonyManager.NETWORK_TYPE_HSDPA:
3573 bin = DATA_CONNECTION_HSDPA;
3574 break;
3575 case TelephonyManager.NETWORK_TYPE_HSUPA:
3576 bin = DATA_CONNECTION_HSUPA;
3577 break;
3578 case TelephonyManager.NETWORK_TYPE_HSPA:
3579 bin = DATA_CONNECTION_HSPA;
3580 break;
3581 case TelephonyManager.NETWORK_TYPE_IDEN:
3582 bin = DATA_CONNECTION_IDEN;
3583 break;
3584 case TelephonyManager.NETWORK_TYPE_EVDO_B:
3585 bin = DATA_CONNECTION_EVDO_B;
3586 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07003587 case TelephonyManager.NETWORK_TYPE_LTE:
3588 bin = DATA_CONNECTION_LTE;
3589 break;
3590 case TelephonyManager.NETWORK_TYPE_EHRPD:
3591 bin = DATA_CONNECTION_EHRPD;
3592 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08003593 case TelephonyManager.NETWORK_TYPE_HSPAP:
3594 bin = DATA_CONNECTION_HSPAP;
3595 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07003596 default:
3597 bin = DATA_CONNECTION_OTHER;
3598 break;
3599 }
3600 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003601 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003602 if (mPhoneDataConnectionType != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003603 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003604 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003605 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
3606 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003607 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
3608 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003609 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003610 if (mPhoneDataConnectionType >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003611 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003612 elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003613 }
3614 mPhoneDataConnectionType = bin;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003615 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003616 }
3617 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003618
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003619 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07003620 if (!mWifiOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003621 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003622 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003623 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003624 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
3625 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003626 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003627 mWifiOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003628 mWifiOnTimer.startRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003629 scheduleSyncExternalStatsLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003630 }
3631 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003632
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003633 public void noteWifiOffLocked() {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003634 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003635 final long uptime = SystemClock.uptimeMillis();
The Android Open Source Project10592532009-03-18 17:39:46 -07003636 if (mWifiOn) {
Dianne Hackborn3251b902014-06-20 14:40:53 -07003637 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003638 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
3639 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003640 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003641 mWifiOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003642 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003643 scheduleSyncExternalStatsLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003644 }
3645 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003646
3647 public void noteAudioOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003648 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003649 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003650 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003651 if (mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003652 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003653 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
3654 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003655 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003656 mAudioOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003657 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003658 mAudioOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003659 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003660 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003661
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003662 public void noteAudioOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003663 if (mAudioOnNesting == 0) {
3664 return;
3665 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003666 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003667 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003668 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003669 if (--mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003670 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003671 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3672 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003673 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003674 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003675 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003676 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003677 }
3678
3679 public void noteVideoOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003680 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003681 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003682 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003683 if (mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003684 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003685 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
3686 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003687 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003688 mVideoOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003689 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003690 mVideoOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003691 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003692 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003693
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003694 public void noteVideoOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003695 if (mVideoOnNesting == 0) {
3696 return;
3697 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003698 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003699 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003700 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003701 if (--mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003702 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003703 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3704 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003705 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003706 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003707 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003708 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003709 }
3710
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003711 public void noteResetAudioLocked() {
3712 if (mAudioOnNesting > 0) {
3713 final long elapsedRealtime = SystemClock.elapsedRealtime();
3714 final long uptime = SystemClock.uptimeMillis();
3715 mAudioOnNesting = 0;
3716 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
3717 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3718 + Integer.toHexString(mHistoryCur.states));
3719 addHistoryRecordLocked(elapsedRealtime, uptime);
3720 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime);
3721 for (int i=0; i<mUidStats.size(); i++) {
3722 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3723 uid.noteResetAudioLocked(elapsedRealtime);
3724 }
3725 }
3726 }
3727
3728 public void noteResetVideoLocked() {
3729 if (mVideoOnNesting > 0) {
3730 final long elapsedRealtime = SystemClock.elapsedRealtime();
3731 final long uptime = SystemClock.uptimeMillis();
3732 mAudioOnNesting = 0;
3733 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
3734 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3735 + Integer.toHexString(mHistoryCur.states));
3736 addHistoryRecordLocked(elapsedRealtime, uptime);
3737 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime);
3738 for (int i=0; i<mUidStats.size(); i++) {
3739 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3740 uid.noteResetVideoLocked(elapsedRealtime);
3741 }
3742 }
3743 }
3744
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003745 public void noteActivityResumedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003746 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003747 getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003748 }
3749
3750 public void noteActivityPausedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003751 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003752 getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003753 }
3754
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003755 public void noteVibratorOnLocked(int uid, long durationMillis) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003756 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003757 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
3758 }
3759
3760 public void noteVibratorOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003761 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003762 getUidStatsLocked(uid).noteVibratorOffLocked();
3763 }
3764
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003765 public void noteFlashlightOnLocked() {
3766 if (!mFlashlightOn) {
3767 final long elapsedRealtime = SystemClock.elapsedRealtime();
3768 final long uptime = SystemClock.uptimeMillis();
3769 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
3770 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
3771 + Integer.toHexString(mHistoryCur.states));
3772 addHistoryRecordLocked(elapsedRealtime, uptime);
3773 mFlashlightOn = true;
3774 mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
3775 }
3776 }
3777
3778 public void noteFlashlightOffLocked() {
3779 final long elapsedRealtime = SystemClock.elapsedRealtime();
3780 final long uptime = SystemClock.uptimeMillis();
3781 if (mFlashlightOn) {
3782 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
3783 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
3784 + Integer.toHexString(mHistoryCur.states));
3785 addHistoryRecordLocked(elapsedRealtime, uptime);
3786 mFlashlightOn = false;
3787 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
3788 }
3789 }
3790
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003791 public void noteWifiRunningLocked(WorkSource ws) {
3792 if (!mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003793 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003794 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003795 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003796 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
3797 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003798 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003799 mGlobalWifiRunning = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003800 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003801 int N = ws.size();
3802 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003803 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003804 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003805 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003806 scheduleSyncExternalStatsLocked();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003807 } else {
3808 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003809 }
3810 }
3811
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003812 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
3813 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003814 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003815 int N = oldWs.size();
3816 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003817 int uid = mapUid(oldWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003818 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003819 }
3820 N = newWs.size();
3821 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003822 int uid = mapUid(newWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003823 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003824 }
3825 } else {
3826 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
3827 }
3828 }
3829
3830 public void noteWifiStoppedLocked(WorkSource ws) {
3831 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003832 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003833 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003834 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003835 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
3836 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003837 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003838 mGlobalWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003839 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003840 int N = ws.size();
3841 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003842 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003843 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003844 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003845 scheduleSyncExternalStatsLocked();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003846 } else {
3847 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003848 }
3849 }
3850
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003851 public void noteWifiStateLocked(int wifiState, String accessPoint) {
3852 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
3853 if (mWifiState != wifiState) {
3854 final long elapsedRealtime = SystemClock.elapsedRealtime();
3855 if (mWifiState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003856 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003857 }
3858 mWifiState = wifiState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003859 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003860 scheduleSyncExternalStatsLocked();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003861 }
3862 }
3863
Dianne Hackborn3251b902014-06-20 14:40:53 -07003864 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
3865 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
3866 if (mWifiSupplState != supplState) {
3867 final long elapsedRealtime = SystemClock.elapsedRealtime();
3868 final long uptime = SystemClock.uptimeMillis();
3869 if (mWifiSupplState >= 0) {
3870 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime);
3871 }
3872 mWifiSupplState = supplState;
3873 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime);
3874 mHistoryCur.states2 =
3875 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
3876 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
3877 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
3878 + Integer.toHexString(mHistoryCur.states2));
3879 addHistoryRecordLocked(elapsedRealtime, uptime);
3880 }
3881 }
3882
3883 void stopAllWifiSignalStrengthTimersLocked(int except) {
3884 final long elapsedRealtime = SystemClock.elapsedRealtime();
3885 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
3886 if (i == except) {
3887 continue;
3888 }
3889 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) {
3890 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
3891 }
3892 }
3893 }
3894
3895 public void noteWifiRssiChangedLocked(int newRssi) {
3896 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
3897 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
3898 if (mWifiSignalStrengthBin != strengthBin) {
3899 final long elapsedRealtime = SystemClock.elapsedRealtime();
3900 final long uptime = SystemClock.uptimeMillis();
3901 if (mWifiSignalStrengthBin >= 0) {
3902 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked(
3903 elapsedRealtime);
3904 }
3905 if (strengthBin >= 0) {
3906 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
3907 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
3908 }
3909 mHistoryCur.states2 =
3910 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
3911 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
3912 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
3913 + Integer.toHexString(mHistoryCur.states2));
3914 addHistoryRecordLocked(elapsedRealtime, uptime);
3915 } else {
3916 stopAllWifiSignalStrengthTimersLocked(-1);
3917 }
3918 mWifiSignalStrengthBin = strengthBin;
3919 }
3920 }
3921
The Android Open Source Project10592532009-03-18 17:39:46 -07003922 public void noteBluetoothOnLocked() {
3923 if (!mBluetoothOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003924 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003925 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003926 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003927 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
3928 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003929 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003930 mBluetoothOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003931 mBluetoothOnTimer.startRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003932 scheduleSyncExternalStatsLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003933 }
3934 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003935
The Android Open Source Project10592532009-03-18 17:39:46 -07003936 public void noteBluetoothOffLocked() {
3937 if (mBluetoothOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003938 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003939 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003940 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003941 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
3942 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003943 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003944 mBluetoothOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003945 mBluetoothOnTimer.stopRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003946 scheduleSyncExternalStatsLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003947 }
3948 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003949
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003950 public void noteBluetoothStateLocked(int bluetoothState) {
3951 if (DEBUG) Log.i(TAG, "Bluetooth state -> " + bluetoothState);
3952 if (mBluetoothState != bluetoothState) {
3953 final long elapsedRealtime = SystemClock.elapsedRealtime();
3954 if (mBluetoothState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003955 mBluetoothStateTimer[mBluetoothState].stopRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003956 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003957 mBluetoothState = bluetoothState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003958 mBluetoothStateTimer[bluetoothState].startRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003959 }
3960 }
3961
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003962 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003963
The Android Open Source Project10592532009-03-18 17:39:46 -07003964 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003965 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003966 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003967 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003968 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003969 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003970 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
3971 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003972 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003973 }
3974 mWifiFullLockNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003975 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003976 }
3977
3978 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003979 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003980 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003981 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003982 mWifiFullLockNesting--;
3983 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003984 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003985 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
3986 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003987 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003988 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003989 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003990 }
3991
Nick Pelly6ccaa542012-06-15 15:22:47 -07003992 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003993
Nick Pelly6ccaa542012-06-15 15:22:47 -07003994 public void noteWifiScanStartedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003995 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003996 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003997 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003998 if (mWifiScanNesting == 0) {
3999 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
4000 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004001 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004002 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004003 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004004 mWifiScanNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004005 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07004006 }
4007
Nick Pelly6ccaa542012-06-15 15:22:47 -07004008 public void noteWifiScanStoppedLocked(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();
Dianne Hackborn40c87252014-03-19 16:55:40 -07004011 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07004012 mWifiScanNesting--;
4013 if (mWifiScanNesting == 0) {
4014 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
4015 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004016 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004017 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004018 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004019 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07004020 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004021
Robert Greenwalta029ea12013-09-25 16:38:12 -07004022 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004023 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004024 final long elapsedRealtime = SystemClock.elapsedRealtime();
4025 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004026 }
4027
4028 public void noteWifiBatchedScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004029 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004030 final long elapsedRealtime = SystemClock.elapsedRealtime();
4031 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004032 }
4033
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004034 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004035
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004036 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004037 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004038 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07004039 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004040 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004041 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004042 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
4043 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004044 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004045 }
4046 mWifiMulticastNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004047 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004048 }
4049
4050 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004051 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004052 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07004053 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004054 mWifiMulticastNesting--;
4055 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004056 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004057 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
4058 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004059 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004060 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004061 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004062 }
4063
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004064 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
4065 int N = ws.size();
4066 for (int i=0; i<N; i++) {
4067 noteFullWifiLockAcquiredLocked(ws.get(i));
4068 }
4069 }
4070
4071 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
4072 int N = ws.size();
4073 for (int i=0; i<N; i++) {
4074 noteFullWifiLockReleasedLocked(ws.get(i));
4075 }
4076 }
4077
Nick Pelly6ccaa542012-06-15 15:22:47 -07004078 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004079 int N = ws.size();
4080 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004081 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004082 }
4083 }
4084
Nick Pelly6ccaa542012-06-15 15:22:47 -07004085 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004086 int N = ws.size();
4087 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004088 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004089 }
4090 }
4091
Robert Greenwalta029ea12013-09-25 16:38:12 -07004092 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
4093 int N = ws.size();
4094 for (int i=0; i<N; i++) {
4095 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
4096 }
4097 }
4098
4099 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
4100 int N = ws.size();
4101 for (int i=0; i<N; i++) {
4102 noteWifiBatchedScanStoppedLocked(ws.get(i));
4103 }
4104 }
4105
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004106 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
4107 int N = ws.size();
4108 for (int i=0; i<N; i++) {
4109 noteWifiMulticastEnabledLocked(ws.get(i));
4110 }
4111 }
4112
4113 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
4114 int N = ws.size();
4115 for (int i=0; i<N; i++) {
4116 noteWifiMulticastDisabledLocked(ws.get(i));
4117 }
4118 }
4119
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004120 private static String[] includeInStringArray(String[] array, String str) {
4121 if (ArrayUtils.indexOf(array, str) >= 0) {
4122 return array;
4123 }
4124 String[] newArray = new String[array.length+1];
4125 System.arraycopy(array, 0, newArray, 0, array.length);
4126 newArray[array.length] = str;
4127 return newArray;
4128 }
4129
4130 private static String[] excludeFromStringArray(String[] array, String str) {
4131 int index = ArrayUtils.indexOf(array, str);
4132 if (index >= 0) {
4133 String[] newArray = new String[array.length-1];
4134 if (index > 0) {
4135 System.arraycopy(array, 0, newArray, 0, index);
4136 }
4137 if (index < array.length-1) {
4138 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
4139 }
4140 return newArray;
4141 }
4142 return array;
4143 }
4144
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004145 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07004146 if (TextUtils.isEmpty(iface)) return;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004147 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004148 mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
4149 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004150 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004151 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
4152 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004153 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004154 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004155 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
4156 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004157 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004158 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
4159 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004160 }
4161 }
4162
4163 public void noteNetworkStatsEnabledLocked() {
4164 // During device boot, qtaguid isn't enabled until after the inital
4165 // loading of battery stats. Now that they're enabled, take our initial
4166 // snapshot for future delta calculation.
Adam Lesinskie08af192015-03-25 16:42:59 -07004167 final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
4168 updateMobileRadioStateLocked(elapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07004169 updateWifiStateLocked(null);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004170 }
4171
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004172 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
4173 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004174 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004175
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004176 @Override public int getScreenOnCount(int which) {
4177 return mScreenOnTimer.getCountLocked(which);
4178 }
4179
Dianne Hackborn617f8772009-03-31 15:04:46 -07004180 @Override public long getScreenBrightnessTime(int brightnessBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004181 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004182 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004183 elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004184 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004185
Jeff Browne95c3cd2014-05-02 16:59:26 -07004186 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
4187 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004188 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004189
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004190 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) {
4191 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004192 }
4193
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004194 @Override public int getPowerSaveModeEnabledCount(int which) {
4195 return mPowerSaveModeEnabledTimer.getCountLocked(which);
4196 }
4197
4198 @Override public long getDeviceIdleModeEnabledTime(long elapsedRealtimeUs, int which) {
4199 return mDeviceIdleModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4200 }
4201
4202 @Override public int getDeviceIdleModeEnabledCount(int which) {
4203 return mDeviceIdleModeEnabledTimer.getCountLocked(which);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004204 }
4205
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004206 @Override public long getDeviceIdlingTime(long elapsedRealtimeUs, int which) {
4207 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4208 }
4209
4210 @Override public int getDeviceIdlingCount(int which) {
4211 return mDeviceIdlingTimer.getCountLocked(which);
4212 }
4213
Dianne Hackborn1e01d162014-12-04 17:46:42 -08004214 @Override public int getNumConnectivityChange(int which) {
4215 int val = mNumConnectivityChange;
4216 if (which == STATS_CURRENT) {
4217 val -= mLoadedNumConnectivityChange;
4218 } else if (which == STATS_SINCE_UNPLUGGED) {
4219 val -= mUnpluggedNumConnectivityChange;
4220 }
4221 return val;
4222 }
4223
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004224 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
4225 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004226 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004227
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004228 @Override public int getPhoneOnCount(int which) {
4229 return mPhoneOnTimer.getCountLocked(which);
4230 }
4231
Dianne Hackborn627bba72009-03-24 22:32:56 -07004232 @Override public long getPhoneSignalStrengthTime(int strengthBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004233 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004234 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004235 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004236 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004237
4238 @Override public long getPhoneSignalScanningTime(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004239 long elapsedRealtimeUs, int which) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07004240 return mPhoneSignalScanningTimer.getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004241 elapsedRealtimeUs, which);
Amith Yamasanif37447b2009-10-08 18:28:01 -07004242 }
4243
Catherine Liufb900812012-07-17 14:12:56 -05004244 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
4245 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004246 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004247
Dianne Hackborn627bba72009-03-24 22:32:56 -07004248 @Override public long getPhoneDataConnectionTime(int dataType,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004249 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004250 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004251 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004252 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004253
Dianne Hackborn617f8772009-03-31 15:04:46 -07004254 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004255 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004256 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004257
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004258 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
4259 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004260 }
4261
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004262 @Override public int getMobileRadioActiveCount(int which) {
4263 return mMobileRadioActiveTimer.getCountLocked(which);
4264 }
4265
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004266 @Override public long getMobileRadioActiveAdjustedTime(int which) {
4267 return mMobileRadioActiveAdjustedTime.getCountLocked(which);
4268 }
4269
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004270 @Override public long getMobileRadioActiveUnknownTime(int which) {
4271 return mMobileRadioActiveUnknownTime.getCountLocked(which);
4272 }
4273
4274 @Override public int getMobileRadioActiveUnknownCount(int which) {
4275 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
4276 }
4277
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004278 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
4279 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004280 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004281
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004282 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
4283 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07004284 }
4285
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004286 @Override public long getWifiStateTime(int wifiState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004287 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004288 return mWifiStateTimer[wifiState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004289 elapsedRealtimeUs, which);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004290 }
4291
4292 @Override public int getWifiStateCount(int wifiState, int which) {
4293 return mWifiStateTimer[wifiState].getCountLocked(which);
4294 }
4295
Dianne Hackborn3251b902014-06-20 14:40:53 -07004296 @Override public long getWifiSupplStateTime(int state,
4297 long elapsedRealtimeUs, int which) {
4298 return mWifiSupplStateTimer[state].getTotalTimeLocked(
4299 elapsedRealtimeUs, which);
4300 }
4301
4302 @Override public int getWifiSupplStateCount(int state, int which) {
4303 return mWifiSupplStateTimer[state].getCountLocked(which);
4304 }
4305
4306 @Override public long getWifiSignalStrengthTime(int strengthBin,
4307 long elapsedRealtimeUs, int which) {
4308 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
4309 elapsedRealtimeUs, which);
4310 }
4311
4312 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) {
4313 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which);
4314 }
4315
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004316 @Override public long getBluetoothOnTime(long elapsedRealtimeUs, int which) {
4317 return mBluetoothOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004318 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004319
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004320 @Override public long getBluetoothStateTime(int bluetoothState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004321 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004322 return mBluetoothStateTimer[bluetoothState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004323 elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004324 }
4325
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004326 @Override public int getBluetoothStateCount(int bluetoothState, int which) {
4327 return mBluetoothStateTimer[bluetoothState].getCountLocked(which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004328 }
4329
Adam Lesinski17390762015-04-10 13:17:47 -07004330 @Override public boolean hasBluetoothActivityReporting() {
4331 return mHasBluetoothEnergyReporting;
4332 }
4333
Adam Lesinski33dac552015-03-09 15:24:48 -07004334 @Override public long getBluetoothControllerActivity(int type, int which) {
4335 if (type >= 0 && type < mBluetoothActivityCounters.length) {
4336 return mBluetoothActivityCounters[type].getCountLocked(which);
4337 }
4338 return 0;
4339 }
4340
Adam Lesinski17390762015-04-10 13:17:47 -07004341 @Override public boolean hasWifiActivityReporting() {
4342 return mHasWifiEnergyReporting;
4343 }
4344
Adam Lesinski33dac552015-03-09 15:24:48 -07004345 @Override public long getWifiControllerActivity(int type, int which) {
4346 if (type >= 0 && type < mWifiActivityCounters.length) {
4347 return mWifiActivityCounters[type].getCountLocked(which);
4348 }
4349 return 0;
4350 }
4351
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004352 @Override public long getFlashlightOnTime(long elapsedRealtimeUs, int which) {
4353 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4354 }
4355
4356 @Override public long getFlashlightOnCount(int which) {
4357 return mFlashlightOnTimer.getCountLocked(which);
4358 }
4359
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004360 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004361 public long getNetworkActivityBytes(int type, int which) {
4362 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
4363 return mNetworkByteActivityCounters[type].getCountLocked(which);
4364 } else {
4365 return 0;
4366 }
4367 }
4368
4369 @Override
4370 public long getNetworkActivityPackets(int type, int which) {
4371 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
4372 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004373 } else {
4374 return 0;
4375 }
4376 }
4377
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07004378 boolean isStartClockTimeValid() {
4379 return mStartClockTime > 365*24*60*60*1000L;
4380 }
4381
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08004382 @Override public long getStartClockTime() {
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07004383 if (!isStartClockTimeValid()) {
4384 // If the last clock time we got was very small, then we hadn't had a real
4385 // time yet, so try to get it again.
4386 mStartClockTime = System.currentTimeMillis();
4387 if (isStartClockTimeValid()) {
4388 recordCurrentTimeChangeLocked(mStartClockTime, SystemClock.elapsedRealtime(),
4389 SystemClock.uptimeMillis());
4390 }
4391 }
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;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004440
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004441 StopwatchTimer mForegroundActivityTimer;
4442
Dianne Hackborn61659e52014-07-09 16:13:01 -07004443 static final int PROCESS_STATE_NONE = NUM_PROCESS_STATE;
4444 int mProcessState = PROCESS_STATE_NONE;
4445 StopwatchTimer[] mProcessStateTimer;
4446
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004447 BatchTimer mVibratorOnTimer;
4448
Dianne Hackborn617f8772009-03-31 15:04:46 -07004449 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004450
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004451 LongSamplingCounter[] mNetworkByteActivityCounters;
4452 LongSamplingCounter[] mNetworkPacketActivityCounters;
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004453 LongSamplingCounter mMobileRadioActiveTime;
4454 LongSamplingCounter mMobileRadioActiveCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004456 /**
Adam Lesinskie08af192015-03-25 16:42:59 -07004457 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode.
4458 */
4459 LongSamplingCounter[] mWifiControllerTime =
4460 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
4461
4462 /**
4463 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode.
4464 */
4465 LongSamplingCounter[] mBluetoothControllerTime =
4466 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
4467
4468 /**
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08004469 * The CPU times we had at the last history details update.
4470 */
4471 long mLastStepUserTime;
4472 long mLastStepSystemTime;
4473 long mCurStepUserTime;
4474 long mCurStepSystemTime;
4475
4476 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004477 * The statistics we have collected for this uid's wake locks.
4478 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004479 final OverflowArrayMap<Wakelock> mWakelockStats = new OverflowArrayMap<Wakelock>() {
4480 @Override public Wakelock instantiateObject() { return new Wakelock(); }
4481 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482
4483 /**
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004484 * The statistics we have collected for this uid's syncs.
4485 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004486 final OverflowArrayMap<StopwatchTimer> mSyncStats = new OverflowArrayMap<StopwatchTimer>() {
4487 @Override public StopwatchTimer instantiateObject() {
4488 return new StopwatchTimer(Uid.this, SYNC, null, mOnBatteryTimeBase);
4489 }
4490 };
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004491
4492 /**
4493 * The statistics we have collected for this uid's jobs.
4494 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004495 final OverflowArrayMap<StopwatchTimer> mJobStats = new OverflowArrayMap<StopwatchTimer>() {
4496 @Override public StopwatchTimer instantiateObject() {
4497 return new StopwatchTimer(Uid.this, JOB, null, mOnBatteryTimeBase);
4498 }
4499 };
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004500
4501 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004502 * The statistics we have collected for this uid's sensor activations.
4503 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004504 final SparseArray<Sensor> mSensorStats = new SparseArray<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004505
4506 /**
4507 * The statistics we have collected for this uid's processes.
4508 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004509 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510
4511 /**
4512 * The statistics we have collected for this uid's processes.
4513 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004514 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004515
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004516 /**
4517 * The transient wake stats we have collected for this uid's pids.
4518 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004519 final SparseArray<Pid> mPids = new SparseArray<>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 public Uid(int uid) {
4522 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004523 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004524 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004525 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004526 mFullWifiLockTimers, mOnBatteryTimeBase);
Nick Pelly6ccaa542012-06-15 15:22:47 -07004527 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004528 mWifiScanTimers, mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004529 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004530 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004531 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn61659e52014-07-09 16:13:01 -07004532 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004533 }
4534
4535 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004536 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004537 return mWakelockStats.getMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004538 }
4539
4540 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004541 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004542 return mSyncStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004543 }
4544
4545 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004546 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004547 return mJobStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004548 }
4549
4550 @Override
Dianne Hackborn61659e52014-07-09 16:13:01 -07004551 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 return mSensorStats;
4553 }
4554
4555 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004556 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004557 return mProcessStats;
4558 }
4559
4560 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004561 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004562 return mPackageStats;
4563 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004564
4565 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004566 public int getUid() {
4567 return mUid;
4568 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004569
4570 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004571 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004572 if (!mWifiRunning) {
4573 mWifiRunning = true;
4574 if (mWifiRunningTimer == null) {
4575 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004576 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004577 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004578 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004579 }
4580 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004581
Dianne Hackborn617f8772009-03-31 15:04:46 -07004582 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004583 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004584 if (mWifiRunning) {
4585 mWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004586 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004587 }
4588 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004589
Dianne Hackborn617f8772009-03-31 15:04:46 -07004590 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004591 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07004592 if (!mFullWifiLockOut) {
4593 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004594 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004595 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004596 mFullWifiLockTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004597 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004598 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004599 }
4600 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004601
The Android Open Source Project10592532009-03-18 17:39:46 -07004602 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004603 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07004604 if (mFullWifiLockOut) {
4605 mFullWifiLockOut = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004606 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004607 }
4608 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004609
The Android Open Source Project10592532009-03-18 17:39:46 -07004610 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004611 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004612 if (!mWifiScanStarted) {
4613 mWifiScanStarted = true;
4614 if (mWifiScanTimer == null) {
4615 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004616 mWifiScanTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004617 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004618 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004619 }
4620 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004621
The Android Open Source Project10592532009-03-18 17:39:46 -07004622 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004623 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004624 if (mWifiScanStarted) {
4625 mWifiScanStarted = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004626 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004627 }
4628 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004629
4630 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004631 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004632 int bin = 0;
4633 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
4634 csph = csph >> 3;
4635 bin++;
4636 }
4637
4638 if (mWifiBatchedScanBinStarted == bin) return;
4639
4640 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
4641 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004642 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004643 }
4644 mWifiBatchedScanBinStarted = bin;
4645 if (mWifiBatchedScanTimer[bin] == null) {
4646 makeWifiBatchedScanBin(bin, null);
4647 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004648 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004649 }
4650
4651 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004652 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004653 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
4654 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004655 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004656 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4657 }
4658 }
4659
4660 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004661 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004662 if (!mWifiMulticastEnabled) {
4663 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004664 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004665 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004666 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004667 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004668 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004669 }
4670 }
4671
4672 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004673 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004674 if (mWifiMulticastEnabled) {
4675 mWifiMulticastEnabled = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004676 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004677 }
4678 }
4679
Adam Lesinskie08af192015-03-25 16:42:59 -07004680 public void noteWifiControllerActivityLocked(int type, long timeMs) {
4681 if (mWifiControllerTime[type] == null) {
4682 mWifiControllerTime[type] = new LongSamplingCounter(mOnBatteryTimeBase);
4683 }
4684 mWifiControllerTime[type].addCountLocked(timeMs);
4685 }
4686
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004687 public StopwatchTimer createAudioTurnedOnTimerLocked() {
4688 if (mAudioTurnedOnTimer == null) {
4689 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004690 mAudioTurnedOnTimers, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004691 }
4692 return mAudioTurnedOnTimer;
4693 }
4694
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004695 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004696 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4697 }
4698
4699 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
4700 if (mAudioTurnedOnTimer != null) {
4701 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004702 }
4703 }
4704
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004705 public void noteResetAudioLocked(long elapsedRealtimeMs) {
4706 if (mAudioTurnedOnTimer != null) {
4707 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004708 }
4709 }
4710
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004711 public StopwatchTimer createVideoTurnedOnTimerLocked() {
4712 if (mVideoTurnedOnTimer == null) {
4713 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004714 mVideoTurnedOnTimers, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004715 }
4716 return mVideoTurnedOnTimer;
4717 }
4718
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004719 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004720 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4721 }
4722
4723 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
4724 if (mVideoTurnedOnTimer != null) {
4725 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004726 }
4727 }
4728
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004729 public void noteResetVideoLocked(long elapsedRealtimeMs) {
4730 if (mVideoTurnedOnTimer != null) {
4731 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004732 }
4733 }
4734
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004735 public StopwatchTimer createForegroundActivityTimerLocked() {
4736 if (mForegroundActivityTimer == null) {
4737 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004738 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004739 }
4740 return mForegroundActivityTimer;
4741 }
4742
4743 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004744 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004745 // We always start, since we want multiple foreground PIDs to nest
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004746 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004747 }
4748
4749 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004750 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004751 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004752 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004753 }
4754 }
4755
Dianne Hackborn61659e52014-07-09 16:13:01 -07004756 void updateUidProcessStateLocked(int state, long elapsedRealtimeMs) {
4757 if (mProcessState == state) return;
4758
4759 if (mProcessState != PROCESS_STATE_NONE) {
4760 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs);
4761 }
4762 mProcessState = state;
4763 if (state != PROCESS_STATE_NONE) {
4764 if (mProcessStateTimer[state] == null) {
4765 makeProcessState(state, null);
4766 }
4767 mProcessStateTimer[state].startRunningLocked(elapsedRealtimeMs);
4768 }
4769 }
4770
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004771 public BatchTimer createVibratorOnTimerLocked() {
4772 if (mVibratorOnTimer == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004773 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004774 }
4775 return mVibratorOnTimer;
4776 }
4777
4778 public void noteVibratorOnLocked(long durationMillis) {
4779 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
4780 }
4781
4782 public void noteVibratorOffLocked() {
4783 if (mVibratorOnTimer != null) {
4784 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004785 }
4786 }
4787
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004788 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004789 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004790 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004791 return 0;
4792 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004793 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004794 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004795
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004796 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004797 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004798 if (mFullWifiLockTimer == null) {
4799 return 0;
4800 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004801 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004802 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004803
4804 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004805 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004806 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004807 return 0;
4808 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004809 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004810 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004811
4812 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07004813 public int getWifiScanCount(int which) {
4814 if (mWifiScanTimer == null) {
4815 return 0;
4816 }
4817 return mWifiScanTimer.getCountLocked(which);
4818 }
4819
4820 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004821 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004822 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
4823 if (mWifiBatchedScanTimer[csphBin] == null) {
4824 return 0;
4825 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004826 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004827 }
4828
4829 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07004830 public int getWifiBatchedScanCount(int csphBin, int which) {
4831 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
4832 if (mWifiBatchedScanTimer[csphBin] == null) {
4833 return 0;
4834 }
4835 return mWifiBatchedScanTimer[csphBin].getCountLocked(which);
4836 }
4837
4838 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004839 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004840 if (mWifiMulticastTimer == null) {
4841 return 0;
4842 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004843 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004844 }
4845
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004846 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004847 public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004848 if (mAudioTurnedOnTimer == null) {
4849 return 0;
4850 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004851 return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004852 }
4853
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004854 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004855 public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004856 if (mVideoTurnedOnTimer == null) {
4857 return 0;
4858 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004859 return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004860 }
4861
Dianne Hackborn617f8772009-03-31 15:04:46 -07004862 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004863 public Timer getForegroundActivityTimer() {
4864 return mForegroundActivityTimer;
4865 }
4866
Dianne Hackborn61659e52014-07-09 16:13:01 -07004867 void makeProcessState(int i, Parcel in) {
4868 if (i < 0 || i >= NUM_PROCESS_STATE) return;
4869
4870 if (in == null) {
4871 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null,
4872 mOnBatteryTimeBase);
4873 } else {
4874 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null,
4875 mOnBatteryTimeBase, in);
4876 }
4877 }
4878
4879 @Override
4880 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) {
4881 if (state < 0 || state >= NUM_PROCESS_STATE) return 0;
4882 if (mProcessStateTimer[state] == null) {
4883 return 0;
4884 }
4885 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which);
4886 }
4887
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004888 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004889 public Timer getVibratorOnTimer() {
4890 return mVibratorOnTimer;
4891 }
4892
4893 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07004894 public void noteUserActivityLocked(int type) {
4895 if (mUserActivityCounters == null) {
4896 initUserActivityLocked();
4897 }
Jeff Browndf693de2012-07-27 12:03:38 -07004898 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
4899 mUserActivityCounters[type].stepAtomic();
4900 } else {
4901 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
4902 new Throwable());
4903 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07004904 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004905
Dianne Hackborn617f8772009-03-31 15:04:46 -07004906 @Override
4907 public boolean hasUserActivity() {
4908 return mUserActivityCounters != null;
4909 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004910
Dianne Hackborn617f8772009-03-31 15:04:46 -07004911 @Override
4912 public int getUserActivityCount(int type, int which) {
4913 if (mUserActivityCounters == null) {
4914 return 0;
4915 }
Evan Millarc64edde2009-04-18 12:26:32 -07004916 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004917 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004918
Robert Greenwalta029ea12013-09-25 16:38:12 -07004919 void makeWifiBatchedScanBin(int i, Parcel in) {
4920 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
4921
4922 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i);
4923 if (collected == null) {
4924 collected = new ArrayList<StopwatchTimer>();
4925 mWifiBatchedScanTimers.put(i, collected);
4926 }
4927 if (in == null) {
4928 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004929 mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004930 } else {
4931 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004932 mOnBatteryTimeBase, in);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004933 }
4934 }
4935
4936
Dianne Hackborn617f8772009-03-31 15:04:46 -07004937 void initUserActivityLocked() {
4938 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
4939 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004940 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004941 }
4942 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004943
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004944 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
4945 if (mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004946 initNetworkActivityLocked();
4947 }
4948 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004949 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
4950 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004951 } else {
4952 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
4953 new Throwable());
4954 }
4955 }
4956
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004957 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
4958 if (mNetworkByteActivityCounters == null) {
4959 initNetworkActivityLocked();
4960 }
4961 mMobileRadioActiveTime.addCountLocked(batteryUptime);
4962 mMobileRadioActiveCount.addCountLocked(1);
4963 }
4964
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004965 @Override
4966 public boolean hasNetworkActivity() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004967 return mNetworkByteActivityCounters != null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004968 }
4969
4970 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004971 public long getNetworkActivityBytes(int type, int which) {
4972 if (mNetworkByteActivityCounters != null && type >= 0
4973 && type < mNetworkByteActivityCounters.length) {
4974 return mNetworkByteActivityCounters[type].getCountLocked(which);
4975 } else {
4976 return 0;
4977 }
4978 }
4979
4980 @Override
4981 public long getNetworkActivityPackets(int type, int which) {
4982 if (mNetworkPacketActivityCounters != null && type >= 0
4983 && type < mNetworkPacketActivityCounters.length) {
4984 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004985 } else {
4986 return 0;
4987 }
4988 }
4989
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004990 @Override
4991 public long getMobileRadioActiveTime(int which) {
4992 return mMobileRadioActiveTime != null
4993 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
4994 }
4995
4996 @Override
4997 public int getMobileRadioActiveCount(int which) {
4998 return mMobileRadioActiveCount != null
4999 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
5000 }
5001
Adam Lesinskie08af192015-03-25 16:42:59 -07005002 @Override
5003 public long getWifiControllerActivity(int type, int which) {
5004 if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES &&
5005 mWifiControllerTime[type] != null) {
5006 return mWifiControllerTime[type].getCountLocked(which);
5007 }
5008 return 0;
5009 }
5010
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005011 void initNetworkActivityLocked() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005012 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
5013 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005014 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005015 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
5016 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005017 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005018 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase);
5019 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005020 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005021
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005022 /**
5023 * Clear all stats for this uid. Returns true if the uid is completely
5024 * inactive so can be dropped.
5025 */
5026 boolean reset() {
5027 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005028
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005029 if (mWifiRunningTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005030 active |= !mWifiRunningTimer.reset(false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005031 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005032 }
5033 if (mFullWifiLockTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005034 active |= !mFullWifiLockTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005035 active |= mFullWifiLockOut;
5036 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005037 if (mWifiScanTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005038 active |= !mWifiScanTimer.reset(false);
Nick Pelly6ccaa542012-06-15 15:22:47 -07005039 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005040 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005041 if (mWifiBatchedScanTimer != null) {
5042 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5043 if (mWifiBatchedScanTimer[i] != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005044 active |= !mWifiBatchedScanTimer[i].reset(false);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005045 }
5046 }
5047 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
5048 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005049 if (mWifiMulticastTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005050 active |= !mWifiMulticastTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005051 active |= mWifiMulticastEnabled;
5052 }
5053 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005054 active |= !mAudioTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005055 }
5056 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005057 active |= !mVideoTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005058 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005059 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005060 active |= !mForegroundActivityTimer.reset(false);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005061 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005062 if (mProcessStateTimer != null) {
5063 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5064 if (mProcessStateTimer[i] != null) {
5065 active |= !mProcessStateTimer[i].reset(false);
5066 }
5067 }
5068 active |= (mProcessState != PROCESS_STATE_NONE);
5069 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005070 if (mVibratorOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005071 if (mVibratorOnTimer.reset(false)) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005072 mVibratorOnTimer.detach();
5073 mVibratorOnTimer = null;
5074 } else {
5075 active = true;
5076 }
5077 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005078
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005079 if (mUserActivityCounters != null) {
5080 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5081 mUserActivityCounters[i].reset(false);
5082 }
5083 }
5084
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005085 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005086 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005087 mNetworkByteActivityCounters[i].reset(false);
5088 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005089 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005090 mMobileRadioActiveTime.reset(false);
5091 mMobileRadioActiveCount.reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005092 }
5093
Adam Lesinskie08af192015-03-25 16:42:59 -07005094 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5095 if (mWifiControllerTime[i] != null) {
5096 mWifiControllerTime[i].reset(false);
5097 }
5098
5099 if (mBluetoothControllerTime[i] != null) {
5100 mBluetoothControllerTime[i].reset(false);
5101 }
5102 }
5103
Dianne Hackbornd953c532014-08-16 18:17:38 -07005104 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
5105 for (int iw=wakeStats.size()-1; iw>=0; iw--) {
5106 Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005107 if (wl.reset()) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005108 wakeStats.removeAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005109 } else {
5110 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005111 }
5112 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005113 mWakelockStats.cleanup();
5114 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap();
5115 for (int is=syncStats.size()-1; is>=0; is--) {
5116 StopwatchTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005117 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005118 syncStats.removeAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005119 timer.detach();
5120 } else {
5121 active = true;
5122 }
5123 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005124 mSyncStats.cleanup();
5125 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
5126 for (int ij=jobStats.size()-1; ij>=0; ij--) {
5127 StopwatchTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005128 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005129 jobStats.removeAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005130 timer.detach();
5131 } else {
5132 active = true;
5133 }
5134 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005135 mJobStats.cleanup();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005136 for (int ise=mSensorStats.size()-1; ise>=0; ise--) {
5137 Sensor s = mSensorStats.valueAt(ise);
5138 if (s.reset()) {
5139 mSensorStats.removeAt(ise);
5140 } else {
5141 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005142 }
5143 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005144 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
5145 Proc proc = mProcessStats.valueAt(ip);
5146 if (proc.mProcessState == PROCESS_STATE_NONE) {
5147 proc.detach();
5148 mProcessStats.removeAt(ip);
5149 } else {
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005150 proc.reset();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005151 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005152 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005153 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005154 if (mPids.size() > 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005155 for (int i=mPids.size()-1; i>=0; i--) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005156 Pid pid = mPids.valueAt(i);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005157 if (pid.mWakeNesting > 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005158 active = true;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005159 } else {
5160 mPids.removeAt(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005161 }
5162 }
5163 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005164 if (mPackageStats.size() > 0) {
5165 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
5166 while (it.hasNext()) {
5167 Map.Entry<String, Pkg> pkgEntry = it.next();
5168 Pkg p = pkgEntry.getValue();
5169 p.detach();
5170 if (p.mServiceStats.size() > 0) {
5171 Iterator<Map.Entry<String, Pkg.Serv>> it2
5172 = p.mServiceStats.entrySet().iterator();
5173 while (it2.hasNext()) {
5174 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
5175 servEntry.getValue().detach();
5176 }
5177 }
5178 }
5179 mPackageStats.clear();
5180 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005181
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005182 mLastStepUserTime = mLastStepSystemTime = 0;
5183 mCurStepUserTime = mCurStepSystemTime = 0;
5184
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005185 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005186 if (mWifiRunningTimer != null) {
5187 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005188 }
5189 if (mFullWifiLockTimer != null) {
5190 mFullWifiLockTimer.detach();
5191 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005192 if (mWifiScanTimer != null) {
5193 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005194 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005195 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5196 if (mWifiBatchedScanTimer[i] != null) {
5197 mWifiBatchedScanTimer[i].detach();
5198 }
5199 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005200 if (mWifiMulticastTimer != null) {
5201 mWifiMulticastTimer.detach();
5202 }
5203 if (mAudioTurnedOnTimer != null) {
5204 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005205 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005206 }
5207 if (mVideoTurnedOnTimer != null) {
5208 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005209 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005210 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005211 if (mForegroundActivityTimer != null) {
5212 mForegroundActivityTimer.detach();
5213 mForegroundActivityTimer = null;
5214 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005215 if (mUserActivityCounters != null) {
5216 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5217 mUserActivityCounters[i].detach();
5218 }
5219 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005220 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005221 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005222 mNetworkByteActivityCounters[i].detach();
5223 mNetworkPacketActivityCounters[i].detach();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005224 }
5225 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005226
5227 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5228 if (mWifiControllerTime[i] != null) {
5229 mWifiControllerTime[i].detach();
5230 }
5231
5232 if (mBluetoothControllerTime[i] != null) {
5233 mBluetoothControllerTime[i].detach();
5234 }
5235 }
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005236 mPids.clear();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005237 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005238
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005239 return !active;
5240 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005241
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005242 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005243 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
5244 int NW = wakeStats.size();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005245 out.writeInt(NW);
5246 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005247 out.writeString(wakeStats.keyAt(iw));
5248 Uid.Wakelock wakelock = wakeStats.valueAt(iw);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005249 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005250 }
5251
Dianne Hackbornd953c532014-08-16 18:17:38 -07005252 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap();
5253 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005254 out.writeInt(NS);
5255 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005256 out.writeString(syncStats.keyAt(is));
5257 StopwatchTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005258 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
5259 }
5260
Dianne Hackbornd953c532014-08-16 18:17:38 -07005261 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
5262 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005263 out.writeInt(NJ);
5264 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005265 out.writeString(jobStats.keyAt(ij));
5266 StopwatchTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005267 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
5268 }
5269
Dianne Hackborn61659e52014-07-09 16:13:01 -07005270 int NSE = mSensorStats.size();
5271 out.writeInt(NSE);
5272 for (int ise=0; ise<NSE; ise++) {
5273 out.writeInt(mSensorStats.keyAt(ise));
5274 Uid.Sensor sensor = mSensorStats.valueAt(ise);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005275 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 }
5277
Dianne Hackborn61659e52014-07-09 16:13:01 -07005278 int NP = mProcessStats.size();
5279 out.writeInt(NP);
5280 for (int ip=0; ip<NP; ip++) {
5281 out.writeString(mProcessStats.keyAt(ip));
5282 Uid.Proc proc = mProcessStats.valueAt(ip);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005283 proc.writeToParcelLocked(out);
5284 }
5285
5286 out.writeInt(mPackageStats.size());
5287 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
5288 out.writeString(pkgEntry.getKey());
5289 Uid.Pkg pkg = pkgEntry.getValue();
5290 pkg.writeToParcelLocked(out);
5291 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005292
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005293 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005294 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005295 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005296 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005297 out.writeInt(0);
5298 }
5299 if (mFullWifiLockTimer != null) {
5300 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005301 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005302 } else {
5303 out.writeInt(0);
5304 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005305 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005306 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005307 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005308 } else {
5309 out.writeInt(0);
5310 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005311 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5312 if (mWifiBatchedScanTimer[i] != null) {
5313 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005314 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005315 } else {
5316 out.writeInt(0);
5317 }
5318 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005319 if (mWifiMulticastTimer != null) {
5320 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005321 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005322 } else {
5323 out.writeInt(0);
5324 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005325
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005326 if (mAudioTurnedOnTimer != null) {
5327 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005328 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005329 } else {
5330 out.writeInt(0);
5331 }
5332 if (mVideoTurnedOnTimer != null) {
5333 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005334 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005335 } else {
5336 out.writeInt(0);
5337 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005338 if (mForegroundActivityTimer != null) {
5339 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005340 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005341 } else {
5342 out.writeInt(0);
5343 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005344 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5345 if (mProcessStateTimer[i] != null) {
5346 out.writeInt(1);
5347 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs);
5348 } else {
5349 out.writeInt(0);
5350 }
5351 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005352 if (mVibratorOnTimer != null) {
5353 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005354 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005355 } else {
5356 out.writeInt(0);
5357 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005358 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07005359 out.writeInt(1);
5360 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5361 mUserActivityCounters[i].writeToParcel(out);
5362 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005363 } else {
5364 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005365 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005366 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005367 out.writeInt(1);
5368 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005369 mNetworkByteActivityCounters[i].writeToParcel(out);
5370 mNetworkPacketActivityCounters[i].writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005371 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005372 mMobileRadioActiveTime.writeToParcel(out);
5373 mMobileRadioActiveCount.writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005374 } else {
5375 out.writeInt(0);
5376 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005377
5378 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5379 if (mWifiControllerTime[i] != null) {
5380 out.writeInt(1);
5381 mWifiControllerTime[i].writeToParcel(out);
5382 } else {
5383 out.writeInt(0);
5384 }
5385 }
5386
5387 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5388 if (mBluetoothControllerTime[i] != null) {
5389 out.writeInt(1);
5390 mBluetoothControllerTime[i].writeToParcel(out);
5391 } else {
5392 out.writeInt(0);
5393 }
5394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005395 }
5396
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005397 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005398 int numWakelocks = in.readInt();
5399 mWakelockStats.clear();
5400 for (int j = 0; j < numWakelocks; j++) {
5401 String wakelockName = in.readString();
5402 Uid.Wakelock wakelock = new Wakelock();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005403 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
Dianne Hackbornd953c532014-08-16 18:17:38 -07005404 mWakelockStats.add(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005405 }
5406
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005407 int numSyncs = in.readInt();
5408 mSyncStats.clear();
5409 for (int j = 0; j < numSyncs; j++) {
5410 String syncName = in.readString();
5411 if (in.readInt() != 0) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005412 mSyncStats.add(syncName,
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005413 new StopwatchTimer(Uid.this, SYNC, null, timeBase, in));
5414 }
5415 }
5416
5417 int numJobs = in.readInt();
5418 mJobStats.clear();
5419 for (int j = 0; j < numJobs; j++) {
5420 String jobName = in.readString();
5421 if (in.readInt() != 0) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005422 mJobStats.add(jobName, new StopwatchTimer(Uid.this, JOB, null, timeBase, in));
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005423 }
5424 }
5425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005426 int numSensors = in.readInt();
5427 mSensorStats.clear();
5428 for (int k = 0; k < numSensors; k++) {
5429 int sensorNumber = in.readInt();
5430 Uid.Sensor sensor = new Sensor(sensorNumber);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005431 sensor.readFromParcelLocked(mOnBatteryTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 mSensorStats.put(sensorNumber, sensor);
5433 }
5434
5435 int numProcs = in.readInt();
5436 mProcessStats.clear();
5437 for (int k = 0; k < numProcs; k++) {
5438 String processName = in.readString();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005439 Uid.Proc proc = new Proc(processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005440 proc.readFromParcelLocked(in);
5441 mProcessStats.put(processName, proc);
5442 }
5443
5444 int numPkgs = in.readInt();
5445 mPackageStats.clear();
5446 for (int l = 0; l < numPkgs; l++) {
5447 String packageName = in.readString();
5448 Uid.Pkg pkg = new Pkg();
5449 pkg.readFromParcelLocked(in);
5450 mPackageStats.put(packageName, pkg);
5451 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005452
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005453 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005454 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005455 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005456 mWifiRunningTimers, mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005457 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005458 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005459 }
5460 mFullWifiLockOut = false;
5461 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005462 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005463 mFullWifiLockTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005464 } else {
5465 mFullWifiLockTimer = null;
5466 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005467 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005468 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005469 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005470 mWifiScanTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005471 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005472 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005473 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005474 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
5475 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5476 if (in.readInt() != 0) {
5477 makeWifiBatchedScanBin(i, in);
5478 } else {
5479 mWifiBatchedScanTimer[i] = null;
5480 }
5481 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005482 mWifiMulticastEnabled = false;
5483 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005484 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005485 mWifiMulticastTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005486 } else {
5487 mWifiMulticastTimer = null;
5488 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005489 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005490 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07005491 mAudioTurnedOnTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005492 } else {
5493 mAudioTurnedOnTimer = null;
5494 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005495 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005496 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07005497 mVideoTurnedOnTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005498 } else {
5499 mVideoTurnedOnTimer = null;
5500 }
5501 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005502 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005503 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005504 } else {
5505 mForegroundActivityTimer = null;
5506 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005507 mProcessState = PROCESS_STATE_NONE;
5508 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5509 if (in.readInt() != 0) {
5510 makeProcessState(i, in);
5511 } else {
5512 mProcessStateTimer[i] = null;
5513 }
5514 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005515 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005516 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005517 } else {
5518 mVibratorOnTimer = null;
5519 }
5520 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07005521 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
5522 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005523 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005524 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005525 } else {
5526 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07005527 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005528 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005529 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
5530 mNetworkPacketActivityCounters
5531 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005532 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005533 mNetworkByteActivityCounters[i]
5534 = new LongSamplingCounter(mOnBatteryTimeBase, in);
5535 mNetworkPacketActivityCounters[i]
5536 = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005537 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005538 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
5539 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005540 } else {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005541 mNetworkByteActivityCounters = null;
5542 mNetworkPacketActivityCounters = null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005543 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005544
5545 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5546 if (in.readInt() != 0) {
5547 mWifiControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
5548 } else {
5549 mWifiControllerTime[i] = null;
5550 }
5551 }
5552
5553 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5554 if (in.readInt() != 0) {
5555 mBluetoothControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
5556 } else {
5557 mBluetoothControllerTime[i] = null;
5558 }
5559 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005560 }
5561
5562 /**
5563 * The statistics associated with a particular wake lock.
5564 */
5565 public final class Wakelock extends BatteryStats.Uid.Wakelock {
5566 /**
5567 * How long (in ms) this uid has been keeping the device partially awake.
5568 */
Evan Millarc64edde2009-04-18 12:26:32 -07005569 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005570
5571 /**
5572 * How long (in ms) this uid has been keeping the device fully awake.
5573 */
Evan Millarc64edde2009-04-18 12:26:32 -07005574 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005575
5576 /**
5577 * How long (in ms) this uid has had a window keeping the device awake.
5578 */
Evan Millarc64edde2009-04-18 12:26:32 -07005579 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005580
5581 /**
5582 * Reads a possibly null Timer from a Parcel. The timer is associated with the
5583 * proper timer pool from the given BatteryStatsImpl object.
5584 *
5585 * @param in the Parcel to be read from.
5586 * return a new Timer, or null.
5587 */
Evan Millarc64edde2009-04-18 12:26:32 -07005588 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005589 TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005590 if (in.readInt() == 0) {
5591 return null;
5592 }
5593
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005594 return new StopwatchTimer(Uid.this, type, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005595 }
5596
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005597 boolean reset() {
5598 boolean wlactive = false;
5599 if (mTimerFull != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005600 wlactive |= !mTimerFull.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005601 }
5602 if (mTimerPartial != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005603 wlactive |= !mTimerPartial.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005604 }
5605 if (mTimerWindow != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005606 wlactive |= !mTimerWindow.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005607 }
5608 if (!wlactive) {
5609 if (mTimerFull != null) {
5610 mTimerFull.detach();
5611 mTimerFull = null;
5612 }
5613 if (mTimerPartial != null) {
5614 mTimerPartial.detach();
5615 mTimerPartial = null;
5616 }
5617 if (mTimerWindow != null) {
5618 mTimerWindow.detach();
5619 mTimerWindow = null;
5620 }
5621 }
5622 return !wlactive;
5623 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005624
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005625 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005626 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005627 mPartialTimers, screenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005628 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005629 mFullTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005630 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005631 mWindowTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005632 }
5633
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005634 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
5635 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
5636 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
5637 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005638 }
5639
5640 @Override
5641 public Timer getWakeTime(int type) {
5642 switch (type) {
5643 case WAKE_TYPE_FULL: return mTimerFull;
5644 case WAKE_TYPE_PARTIAL: return mTimerPartial;
5645 case WAKE_TYPE_WINDOW: return mTimerWindow;
5646 default: throw new IllegalArgumentException("type = " + type);
5647 }
5648 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005649
5650 public StopwatchTimer getStopwatchTimer(int type) {
5651 StopwatchTimer t;
5652 switch (type) {
5653 case WAKE_TYPE_PARTIAL:
5654 t = mTimerPartial;
5655 if (t == null) {
5656 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
5657 mPartialTimers, mOnBatteryScreenOffTimeBase);
5658 mTimerPartial = t;
5659 }
5660 return t;
5661 case WAKE_TYPE_FULL:
5662 t = mTimerFull;
5663 if (t == null) {
5664 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
5665 mFullTimers, mOnBatteryTimeBase);
5666 mTimerFull = t;
5667 }
5668 return t;
5669 case WAKE_TYPE_WINDOW:
5670 t = mTimerWindow;
5671 if (t == null) {
5672 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
5673 mWindowTimers, mOnBatteryTimeBase);
5674 mTimerWindow = t;
5675 }
5676 return t;
5677 default:
5678 throw new IllegalArgumentException("type=" + type);
5679 }
5680 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005681 }
5682
5683 public final class Sensor extends BatteryStats.Uid.Sensor {
5684 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07005685 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005687 public Sensor(int handle) {
5688 mHandle = handle;
5689 }
5690
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005691 private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005692 if (in.readInt() == 0) {
5693 return null;
5694 }
5695
Evan Millarc64edde2009-04-18 12:26:32 -07005696 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07005698 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005699 mSensorTimers.put(mHandle, pool);
5700 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005701 return new StopwatchTimer(Uid.this, 0, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005702 }
5703
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005704 boolean reset() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005705 if (mTimer.reset(true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005706 mTimer = null;
5707 return true;
5708 }
5709 return false;
5710 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005711
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005712 void readFromParcelLocked(TimeBase timeBase, Parcel in) {
5713 mTimer = readTimerFromParcel(timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005714 }
5715
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005716 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
5717 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005718 }
5719
5720 @Override
5721 public Timer getSensorTime() {
5722 return mTimer;
5723 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005724
5725 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005726 public int getHandle() {
5727 return mHandle;
5728 }
5729 }
5730
5731 /**
5732 * The statistics associated with a particular process.
5733 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005734 public final class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005735 /**
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005736 * The name of this process.
5737 */
5738 final String mName;
5739
5740 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -08005741 * Remains true until removed from the stats.
5742 */
5743 boolean mActive = true;
5744
5745 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005746 * Total time (in ms) spent executing in user code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005747 */
5748 long mUserTime;
5749
5750 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005751 * Total time (in ms) spent executing in kernel code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005752 */
5753 long mSystemTime;
5754
5755 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005756 * Amount of time (in ms) the process was running in the foreground.
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005757 */
5758 long mForegroundTime;
5759
5760 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005761 * Number of times the process has been started.
5762 */
5763 int mStarts;
5764
5765 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005766 * Number of times the process has crashed.
5767 */
5768 int mNumCrashes;
5769
5770 /**
5771 * Number of times the process has had an ANR.
5772 */
5773 int mNumAnrs;
5774
5775 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005776 * The amount of user time loaded from a previous save.
5777 */
5778 long mLoadedUserTime;
5779
5780 /**
5781 * The amount of system time loaded from a previous save.
5782 */
5783 long mLoadedSystemTime;
5784
5785 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005786 * The amount of foreground time loaded from a previous save.
5787 */
5788 long mLoadedForegroundTime;
5789
5790 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005791 * The number of times the process has started from a previous save.
5792 */
5793 int mLoadedStarts;
5794
5795 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005796 * Number of times the process has crashed from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005797 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005798 int mLoadedNumCrashes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005799
5800 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005801 * Number of times the process has had an ANR from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005802 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005803 int mLoadedNumAnrs;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005804
5805 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005806 * The amount of user time when last unplugged.
5807 */
5808 long mUnpluggedUserTime;
5809
5810 /**
5811 * The amount of system time when last unplugged.
5812 */
5813 long mUnpluggedSystemTime;
5814
5815 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005816 * The amount of foreground time since unplugged.
5817 */
5818 long mUnpluggedForegroundTime;
5819
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005820 /**
5821 * The number of times the process has started before unplugged.
5822 */
5823 int mUnpluggedStarts;
5824
Dianne Hackborn61659e52014-07-09 16:13:01 -07005825 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005826 * Number of times the process has crashed before unplugged.
5827 */
5828 int mUnpluggedNumCrashes;
5829
5830 /**
5831 * Number of times the process has had an ANR before unplugged.
5832 */
5833 int mUnpluggedNumAnrs;
5834
5835 /**
Dianne Hackborn61659e52014-07-09 16:13:01 -07005836 * Current process state.
5837 */
5838 int mProcessState = PROCESS_STATE_NONE;
5839
Amith Yamasanie43530a2009-08-21 13:11:37 -07005840 SamplingCounter[] mSpeedBins;
5841
Dianne Hackborn287952c2010-09-22 22:34:31 -07005842 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005843
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005844 Proc(String name) {
5845 mName = name;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005846 mOnBatteryTimeBase.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07005847 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005849
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005850 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005851 mUnpluggedUserTime = mUserTime;
5852 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005853 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005854 mUnpluggedStarts = mStarts;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005855 mUnpluggedNumCrashes = mNumCrashes;
5856 mUnpluggedNumAnrs = mNumAnrs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005857 }
5858
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005859 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005860 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005861
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005862 void reset() {
5863 mUserTime = mSystemTime = mForegroundTime = 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005864 mStarts = mNumCrashes = mNumAnrs = 0;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005865 mLoadedUserTime = mLoadedSystemTime = mLoadedForegroundTime = 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005866 mLoadedStarts = mLoadedNumCrashes = mLoadedNumAnrs = 0;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005867 mUnpluggedUserTime = mUnpluggedSystemTime = mUnpluggedForegroundTime = 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005868 mUnpluggedStarts = mUnpluggedNumCrashes = mUnpluggedNumAnrs = 0;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005869 for (int i = 0; i < mSpeedBins.length; i++) {
5870 SamplingCounter c = mSpeedBins[i];
5871 if (c != null) {
5872 c.reset(false);
5873 }
5874 }
5875 mExcessivePower = null;
5876 }
5877
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005878 void detach() {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005879 mActive = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005880 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005881 for (int i = 0; i < mSpeedBins.length; i++) {
5882 SamplingCounter c = mSpeedBins[i];
5883 if (c != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005884 mOnBatteryTimeBase.remove(c);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005885 mSpeedBins[i] = null;
5886 }
5887 }
5888 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005889
Dianne Hackborn287952c2010-09-22 22:34:31 -07005890 public int countExcessivePowers() {
5891 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005892 }
5893
Dianne Hackborn287952c2010-09-22 22:34:31 -07005894 public ExcessivePower getExcessivePower(int i) {
5895 if (mExcessivePower != null) {
5896 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005897 }
5898 return null;
5899 }
5900
5901 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005902 if (mExcessivePower == null) {
5903 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005904 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005905 ExcessivePower ew = new ExcessivePower();
5906 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005907 ew.overTime = overTime;
5908 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07005909 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005910 }
5911
Dianne Hackborn287952c2010-09-22 22:34:31 -07005912 public void addExcessiveCpu(long overTime, long usedTime) {
5913 if (mExcessivePower == null) {
5914 mExcessivePower = new ArrayList<ExcessivePower>();
5915 }
5916 ExcessivePower ew = new ExcessivePower();
5917 ew.type = ExcessivePower.TYPE_CPU;
5918 ew.overTime = overTime;
5919 ew.usedTime = usedTime;
5920 mExcessivePower.add(ew);
5921 }
5922
5923 void writeExcessivePowerToParcelLocked(Parcel out) {
5924 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005925 out.writeInt(0);
5926 return;
5927 }
5928
Dianne Hackborn287952c2010-09-22 22:34:31 -07005929 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005930 out.writeInt(N);
5931 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005932 ExcessivePower ew = mExcessivePower.get(i);
5933 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005934 out.writeLong(ew.overTime);
5935 out.writeLong(ew.usedTime);
5936 }
5937 }
5938
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005939 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005940 final int N = in.readInt();
5941 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005942 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005943 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005944 }
5945
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005946 if (N > 10000) {
5947 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
5948 return false;
5949 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07005950
Dianne Hackborn287952c2010-09-22 22:34:31 -07005951 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005952 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005953 ExcessivePower ew = new ExcessivePower();
5954 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005955 ew.overTime = in.readLong();
5956 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07005957 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005958 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005959 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005960 }
5961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005962 void writeToParcelLocked(Parcel out) {
5963 out.writeLong(mUserTime);
5964 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005965 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005966 out.writeInt(mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005967 out.writeInt(mNumCrashes);
5968 out.writeInt(mNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005969 out.writeLong(mLoadedUserTime);
5970 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005971 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005972 out.writeInt(mLoadedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005973 out.writeInt(mLoadedNumCrashes);
5974 out.writeInt(mLoadedNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 out.writeLong(mUnpluggedUserTime);
5976 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005977 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 out.writeInt(mUnpluggedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005979 out.writeInt(mUnpluggedNumCrashes);
5980 out.writeInt(mUnpluggedNumAnrs);
Amith Yamasanie43530a2009-08-21 13:11:37 -07005981
5982 out.writeInt(mSpeedBins.length);
5983 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005984 SamplingCounter c = mSpeedBins[i];
5985 if (c != null) {
5986 out.writeInt(1);
5987 c.writeToParcel(out);
5988 } else {
5989 out.writeInt(0);
5990 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005991 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005992
Dianne Hackborn287952c2010-09-22 22:34:31 -07005993 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005994 }
5995
5996 void readFromParcelLocked(Parcel in) {
5997 mUserTime = in.readLong();
5998 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005999 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006000 mStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006001 mNumCrashes = in.readInt();
6002 mNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006003 mLoadedUserTime = in.readLong();
6004 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006005 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006006 mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006007 mLoadedNumCrashes = in.readInt();
6008 mLoadedNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006009 mUnpluggedUserTime = in.readLong();
6010 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006011 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006012 mUnpluggedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006013 mUnpluggedNumCrashes = in.readInt();
6014 mUnpluggedNumAnrs = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07006015
6016 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006017 int steps = getCpuSpeedSteps();
6018 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07006019 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006020 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006021 mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006022 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006023 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006024
Dianne Hackborn287952c2010-09-22 22:34:31 -07006025 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 }
6027
6028 public BatteryStatsImpl getBatteryStats() {
6029 return BatteryStatsImpl.this;
6030 }
6031
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08006032 public void addCpuTimeLocked(int utime, int stime, long[] speedStepBins) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006033 mUserTime += utime;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08006034 mCurStepUserTime += utime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006035 mSystemTime += stime;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08006036 mCurStepSystemTime += stime;
6037
6038 for (int i = 0; i < mSpeedBins.length && i < speedStepBins.length; i++) {
6039 long amt = speedStepBins[i];
6040 if (amt != 0) {
6041 SamplingCounter c = mSpeedBins[i];
6042 if (c == null) {
6043 mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase);
6044 }
6045 c.addCountAtomic(speedStepBins[i]);
6046 }
6047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 }
6049
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006050 public void addForegroundTimeLocked(long ttime) {
6051 mForegroundTime += ttime;
6052 }
6053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006054 public void incStartsLocked() {
6055 mStarts++;
6056 }
6057
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006058 public void incNumCrashesLocked() {
6059 mNumCrashes++;
6060 }
6061
6062 public void incNumAnrsLocked() {
6063 mNumAnrs++;
6064 }
6065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08006067 public boolean isActive() {
6068 return mActive;
6069 }
6070
6071 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006072 public long getUserTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006073 long val = mUserTime;
6074 if (which == STATS_CURRENT) {
6075 val -= mLoadedUserTime;
6076 } else if (which == STATS_SINCE_UNPLUGGED) {
6077 val -= mUnpluggedUserTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006078 }
6079 return val;
6080 }
6081
6082 @Override
6083 public long getSystemTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006084 long val = mSystemTime;
6085 if (which == STATS_CURRENT) {
6086 val -= mLoadedSystemTime;
6087 } else if (which == STATS_SINCE_UNPLUGGED) {
6088 val -= mUnpluggedSystemTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006089 }
6090 return val;
6091 }
6092
6093 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006094 public long getForegroundTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006095 long val = mForegroundTime;
6096 if (which == STATS_CURRENT) {
6097 val -= mLoadedForegroundTime;
6098 } else if (which == STATS_SINCE_UNPLUGGED) {
6099 val -= mUnpluggedForegroundTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006100 }
6101 return val;
6102 }
6103
6104 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006105 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006106 int val = mStarts;
6107 if (which == STATS_CURRENT) {
6108 val -= mLoadedStarts;
6109 } else if (which == STATS_SINCE_UNPLUGGED) {
6110 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006111 }
6112 return val;
6113 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006114
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006115 @Override
6116 public int getNumCrashes(int which) {
6117 int val = mNumCrashes;
6118 if (which == STATS_CURRENT) {
6119 val -= mLoadedNumCrashes;
6120 } else if (which == STATS_SINCE_UNPLUGGED) {
6121 val -= mUnpluggedNumCrashes;
6122 }
6123 return val;
6124 }
6125
6126 @Override
6127 public int getNumAnrs(int which) {
6128 int val = mNumAnrs;
6129 if (which == STATS_CURRENT) {
6130 val -= mLoadedNumAnrs;
6131 } else if (which == STATS_SINCE_UNPLUGGED) {
6132 val -= mUnpluggedNumAnrs;
6133 }
6134 return val;
6135 }
6136
Amith Yamasanie43530a2009-08-21 13:11:37 -07006137 @Override
6138 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
6139 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006140 SamplingCounter c = mSpeedBins[speedStep];
6141 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07006142 } else {
6143 return 0;
6144 }
6145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006146 }
6147
6148 /**
6149 * The statistics associated with a particular package.
6150 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006151 public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006152 /**
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006153 * Number of times wakeup alarms have occurred for this app.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006154 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006155 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006156
6157 /**
6158 * The statics we have collected for this package's services.
6159 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006160 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006161
6162 Pkg() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006163 mOnBatteryScreenOffTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006164 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006165
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006166 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006167 }
6168
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006169 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006170 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006171
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006172 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006173 mOnBatteryScreenOffTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006174 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006176 void readFromParcelLocked(Parcel in) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006177 int numWA = in.readInt();
6178 mWakeupAlarms.clear();
6179 for (int i=0; i<numWA; i++) {
6180 String tag = in.readString();
6181 mWakeupAlarms.put(tag, new Counter(mOnBatteryTimeBase, in));
6182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183
6184 int numServs = in.readInt();
6185 mServiceStats.clear();
6186 for (int m = 0; m < numServs; m++) {
6187 String serviceName = in.readString();
6188 Uid.Pkg.Serv serv = new Serv();
6189 mServiceStats.put(serviceName, serv);
6190
6191 serv.readFromParcelLocked(in);
6192 }
6193 }
6194
6195 void writeToParcelLocked(Parcel out) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006196 int numWA = mWakeupAlarms.size();
6197 out.writeInt(numWA);
6198 for (int i=0; i<numWA; i++) {
6199 out.writeString(mWakeupAlarms.keyAt(i));
6200 mWakeupAlarms.valueAt(i).writeToParcel(out);
6201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006202
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006203 final int NS = mServiceStats.size();
6204 out.writeInt(NS);
6205 for (int i=0; i<NS; i++) {
6206 out.writeString(mServiceStats.keyAt(i));
6207 Uid.Pkg.Serv serv = mServiceStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006208 serv.writeToParcelLocked(out);
6209 }
6210 }
6211
6212 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006213 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() {
6214 return mWakeupAlarms;
6215 }
6216
6217 public void noteWakeupAlarmLocked(String tag) {
6218 Counter c = mWakeupAlarms.get(tag);
6219 if (c == null) {
6220 c = new Counter(mOnBatteryTimeBase);
6221 mWakeupAlarms.put(tag, c);
6222 }
6223 c.stepAtomic();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006224 }
6225
6226 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006227 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
6228 return mServiceStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006229 }
6230
6231 /**
6232 * The statistics associated with a particular service.
6233 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006234 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006235 /**
6236 * Total time (ms in battery uptime) the service has been left started.
6237 */
6238 long mStartTime;
6239
6240 /**
6241 * If service has been started and not yet stopped, this is
6242 * when it was started.
6243 */
6244 long mRunningSince;
6245
6246 /**
6247 * True if we are currently running.
6248 */
6249 boolean mRunning;
6250
6251 /**
6252 * Total number of times startService() has been called.
6253 */
6254 int mStarts;
6255
6256 /**
6257 * Total time (ms in battery uptime) the service has been left launched.
6258 */
6259 long mLaunchedTime;
6260
6261 /**
6262 * If service has been launched and not yet exited, this is
6263 * when it was launched (ms in battery uptime).
6264 */
6265 long mLaunchedSince;
6266
6267 /**
6268 * True if we are currently launched.
6269 */
6270 boolean mLaunched;
6271
6272 /**
6273 * Total number times the service has been launched.
6274 */
6275 int mLaunches;
6276
6277 /**
6278 * The amount of time spent started loaded from a previous save
6279 * (ms in battery uptime).
6280 */
6281 long mLoadedStartTime;
6282
6283 /**
6284 * The number of starts loaded from a previous save.
6285 */
6286 int mLoadedStarts;
6287
6288 /**
6289 * The number of launches loaded from a previous save.
6290 */
6291 int mLoadedLaunches;
6292
6293 /**
6294 * The amount of time spent started as of the last run (ms
6295 * in battery uptime).
6296 */
6297 long mLastStartTime;
6298
6299 /**
6300 * The number of starts as of the last run.
6301 */
6302 int mLastStarts;
6303
6304 /**
6305 * The number of launches as of the last run.
6306 */
6307 int mLastLaunches;
6308
6309 /**
6310 * The amount of time spent started when last unplugged (ms
6311 * in battery uptime).
6312 */
6313 long mUnpluggedStartTime;
6314
6315 /**
6316 * The number of starts when last unplugged.
6317 */
6318 int mUnpluggedStarts;
6319
6320 /**
6321 * The number of launches when last unplugged.
6322 */
6323 int mUnpluggedLaunches;
6324
6325 Serv() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006326 mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006327 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006328
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006329 public void onTimeStarted(long elapsedRealtime, long baseUptime,
6330 long baseRealtime) {
6331 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006332 mUnpluggedStarts = mStarts;
6333 mUnpluggedLaunches = mLaunches;
6334 }
6335
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006336 public void onTimeStopped(long elapsedRealtime, long baseUptime,
6337 long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006338 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006339
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006340 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006341 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006342 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006344 void readFromParcelLocked(Parcel in) {
6345 mStartTime = in.readLong();
6346 mRunningSince = in.readLong();
6347 mRunning = in.readInt() != 0;
6348 mStarts = in.readInt();
6349 mLaunchedTime = in.readLong();
6350 mLaunchedSince = in.readLong();
6351 mLaunched = in.readInt() != 0;
6352 mLaunches = in.readInt();
6353 mLoadedStartTime = in.readLong();
6354 mLoadedStarts = in.readInt();
6355 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006356 mLastStartTime = 0;
6357 mLastStarts = 0;
6358 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006359 mUnpluggedStartTime = in.readLong();
6360 mUnpluggedStarts = in.readInt();
6361 mUnpluggedLaunches = in.readInt();
6362 }
6363
6364 void writeToParcelLocked(Parcel out) {
6365 out.writeLong(mStartTime);
6366 out.writeLong(mRunningSince);
6367 out.writeInt(mRunning ? 1 : 0);
6368 out.writeInt(mStarts);
6369 out.writeLong(mLaunchedTime);
6370 out.writeLong(mLaunchedSince);
6371 out.writeInt(mLaunched ? 1 : 0);
6372 out.writeInt(mLaunches);
6373 out.writeLong(mLoadedStartTime);
6374 out.writeInt(mLoadedStarts);
6375 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006376 out.writeLong(mUnpluggedStartTime);
6377 out.writeInt(mUnpluggedStarts);
6378 out.writeInt(mUnpluggedLaunches);
6379 }
6380
6381 long getLaunchTimeToNowLocked(long batteryUptime) {
6382 if (!mLaunched) return mLaunchedTime;
6383 return mLaunchedTime + batteryUptime - mLaunchedSince;
6384 }
6385
6386 long getStartTimeToNowLocked(long batteryUptime) {
6387 if (!mRunning) return mStartTime;
6388 return mStartTime + batteryUptime - mRunningSince;
6389 }
6390
6391 public void startLaunchedLocked() {
6392 if (!mLaunched) {
6393 mLaunches++;
6394 mLaunchedSince = getBatteryUptimeLocked();
6395 mLaunched = true;
6396 }
6397 }
6398
6399 public void stopLaunchedLocked() {
6400 if (mLaunched) {
6401 long time = getBatteryUptimeLocked() - mLaunchedSince;
6402 if (time > 0) {
6403 mLaunchedTime += time;
6404 } else {
6405 mLaunches--;
6406 }
6407 mLaunched = false;
6408 }
6409 }
6410
6411 public void startRunningLocked() {
6412 if (!mRunning) {
6413 mStarts++;
6414 mRunningSince = getBatteryUptimeLocked();
6415 mRunning = true;
6416 }
6417 }
6418
6419 public void stopRunningLocked() {
6420 if (mRunning) {
6421 long time = getBatteryUptimeLocked() - mRunningSince;
6422 if (time > 0) {
6423 mStartTime += time;
6424 } else {
6425 mStarts--;
6426 }
6427 mRunning = false;
6428 }
6429 }
6430
6431 public BatteryStatsImpl getBatteryStats() {
6432 return BatteryStatsImpl.this;
6433 }
6434
6435 @Override
6436 public int getLaunches(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006437 int val = mLaunches;
6438 if (which == STATS_CURRENT) {
6439 val -= mLoadedLaunches;
6440 } else if (which == STATS_SINCE_UNPLUGGED) {
6441 val -= mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006442 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006443 return val;
6444 }
6445
6446 @Override
6447 public long getStartTime(long now, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006448 long val = getStartTimeToNowLocked(now);
6449 if (which == STATS_CURRENT) {
6450 val -= mLoadedStartTime;
6451 } else if (which == STATS_SINCE_UNPLUGGED) {
6452 val -= mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 return val;
6455 }
6456
6457 @Override
6458 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006459 int val = mStarts;
6460 if (which == STATS_CURRENT) {
6461 val -= mLoadedStarts;
6462 } else if (which == STATS_SINCE_UNPLUGGED) {
6463 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006464 }
6465
6466 return val;
6467 }
6468 }
6469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006470 final Serv newServiceStatsLocked() {
6471 return new Serv();
6472 }
6473 }
6474
6475 /**
6476 * Retrieve the statistics object for a particular process, creating
6477 * if needed.
6478 */
6479 public Proc getProcessStatsLocked(String name) {
6480 Proc ps = mProcessStats.get(name);
6481 if (ps == null) {
Dianne Hackborncd0e3352014-08-07 17:08:09 -07006482 ps = new Proc(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006483 mProcessStats.put(name, ps);
6484 }
6485
6486 return ps;
6487 }
6488
Dianne Hackborn61659e52014-07-09 16:13:01 -07006489 public void updateProcessStateLocked(String procName, int state, long elapsedRealtimeMs) {
6490 int procState;
6491 if (state <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
6492 procState = PROCESS_STATE_FOREGROUND;
6493 } else if (state <= ActivityManager.PROCESS_STATE_RECEIVER) {
6494 procState = PROCESS_STATE_ACTIVE;
6495 } else {
6496 procState = PROCESS_STATE_RUNNING;
6497 }
6498 updateRealProcessStateLocked(procName, procState, elapsedRealtimeMs);
6499 }
6500
6501 public void updateRealProcessStateLocked(String procName, int procState,
6502 long elapsedRealtimeMs) {
6503 Proc proc = getProcessStatsLocked(procName);
6504 if (proc.mProcessState != procState) {
6505 boolean changed;
6506 if (procState < proc.mProcessState) {
6507 // Has this process become more important? If so,
6508 // we may need to change the uid if the currrent uid proc state
6509 // is not as important as what we are now setting.
6510 changed = mProcessState > procState;
6511 } else {
6512 // Has this process become less important? If so,
6513 // we may need to change the uid if the current uid proc state
6514 // is the same importance as the old setting.
6515 changed = mProcessState == proc.mProcessState;
6516 }
6517 proc.mProcessState = procState;
6518 if (changed) {
6519 // uid's state may have changed; compute what the new state should be.
6520 int uidProcState = PROCESS_STATE_NONE;
6521 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
6522 proc = mProcessStats.valueAt(ip);
6523 if (proc.mProcessState < uidProcState) {
6524 uidProcState = proc.mProcessState;
6525 }
6526 }
6527 updateUidProcessStateLocked(uidProcState, elapsedRealtimeMs);
6528 }
6529 }
6530 }
6531
Dianne Hackbornb5e31652010-09-07 12:13:55 -07006532 public SparseArray<? extends Pid> getPidStats() {
6533 return mPids;
6534 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006535
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006536 public Pid getPidStatsLocked(int pid) {
6537 Pid p = mPids.get(pid);
6538 if (p == null) {
6539 p = new Pid();
6540 mPids.put(pid, p);
6541 }
6542 return p;
6543 }
6544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006545 /**
6546 * Retrieve the statistics object for a particular service, creating
6547 * if needed.
6548 */
6549 public Pkg getPackageStatsLocked(String name) {
6550 Pkg ps = mPackageStats.get(name);
6551 if (ps == null) {
6552 ps = new Pkg();
6553 mPackageStats.put(name, ps);
6554 }
6555
6556 return ps;
6557 }
6558
6559 /**
6560 * Retrieve the statistics object for a particular service, creating
6561 * if needed.
6562 */
6563 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
6564 Pkg ps = getPackageStatsLocked(pkg);
6565 Pkg.Serv ss = ps.mServiceStats.get(serv);
6566 if (ss == null) {
6567 ss = ps.newServiceStatsLocked();
6568 ps.mServiceStats.put(serv, ss);
6569 }
6570
6571 return ss;
6572 }
6573
Dianne Hackbornd953c532014-08-16 18:17:38 -07006574 public void readSyncSummaryFromParcelLocked(String name, Parcel in) {
6575 StopwatchTimer timer = mSyncStats.instantiateObject();
6576 timer.readSummaryFromParcelLocked(in);
6577 mSyncStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006578 }
6579
Dianne Hackbornd953c532014-08-16 18:17:38 -07006580 public void readJobSummaryFromParcelLocked(String name, Parcel in) {
6581 StopwatchTimer timer = mJobStats.instantiateObject();
6582 timer.readSummaryFromParcelLocked(in);
6583 mJobStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006584 }
6585
Dianne Hackbornd953c532014-08-16 18:17:38 -07006586 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) {
6587 Wakelock wl = new Wakelock();
6588 mWakelockStats.add(wlName, wl);
6589 if (in.readInt() != 0) {
6590 wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006591 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006592 if (in.readInt() != 0) {
6593 wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
6594 }
6595 if (in.readInt() != 0) {
6596 wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006597 }
6598 }
6599
Evan Millarc64edde2009-04-18 12:26:32 -07006600 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006601 Sensor se = mSensorStats.get(sensor);
6602 if (se == null) {
6603 if (!create) {
6604 return null;
6605 }
6606 se = new Sensor(sensor);
6607 mSensorStats.put(sensor, se);
6608 }
Evan Millarc64edde2009-04-18 12:26:32 -07006609 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006610 if (t != null) {
6611 return t;
6612 }
Evan Millarc64edde2009-04-18 12:26:32 -07006613 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006614 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07006615 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006616 mSensorTimers.put(sensor, timers);
6617 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006618 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006619 se.mTimer = t;
6620 return t;
6621 }
6622
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006623 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006624 StopwatchTimer t = mSyncStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006625 if (t != null) {
6626 t.startRunningLocked(elapsedRealtimeMs);
6627 }
6628 }
6629
6630 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006631 StopwatchTimer t = mSyncStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006632 if (t != null) {
6633 t.stopRunningLocked(elapsedRealtimeMs);
6634 }
6635 }
6636
6637 public void noteStartJobLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07006638 StopwatchTimer t = mJobStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006639 if (t != null) {
6640 t.startRunningLocked(elapsedRealtimeMs);
6641 }
6642 }
6643
6644 public void noteStopJobLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006645 StopwatchTimer t = mJobStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006646 if (t != null) {
6647 t.stopRunningLocked(elapsedRealtimeMs);
6648 }
6649 }
6650
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006651 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006652 Wakelock wl = mWakelockStats.startObject(name);
6653 if (wl != null) {
6654 wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006655 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07006656 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006657 Pid p = getPidStatsLocked(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006658 if (p.mWakeNesting++ == 0) {
6659 p.mWakeStartMs = elapsedRealtimeMs;
Dianne Hackbornb8071d792010-09-09 16:45:15 -07006660 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006661 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006662 }
6663
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006664 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006665 Wakelock wl = mWakelockStats.stopObject(name);
6666 if (wl != null) {
6667 wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006668 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07006669 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006670 Pid p = mPids.get(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006671 if (p != null && p.mWakeNesting > 0) {
6672 if (p.mWakeNesting-- == 1) {
6673 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
6674 p.mWakeStartMs = 0;
6675 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006676 }
6677 }
6678 }
6679
6680 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
6681 Proc p = getProcessStatsLocked(proc);
6682 if (p != null) {
6683 p.addExcessiveWake(overTime, usedTime);
6684 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006685 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006686
Dianne Hackborn287952c2010-09-22 22:34:31 -07006687 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
6688 Proc p = getProcessStatsLocked(proc);
6689 if (p != null) {
6690 p.addExcessiveCpu(overTime, usedTime);
6691 }
6692 }
6693
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006694 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006695 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006696 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006697 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006699 }
6700
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006701 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006702 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07006703 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006704 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006705 t.stopRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006707 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006708
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006709 public void noteStartGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006710 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006711 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006712 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006713 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006714 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006715
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006716 public void noteStopGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006717 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006718 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006719 t.stopRunningLocked(elapsedRealtimeMs);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07006720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006721 }
6722
6723 public BatteryStatsImpl getBatteryStats() {
6724 return BatteryStatsImpl.this;
6725 }
6726 }
6727
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006728 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07006729 if (systemDir != null) {
6730 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"),
6731 new File(systemDir, "batterystats.bin.tmp"));
6732 } else {
6733 mFile = null;
6734 }
6735 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006736 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006737 mExternalSync = externalSync;
Jeff Brown6f357d32014-01-15 20:40:55 -08006738 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006739 mStartCount++;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006740 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006741 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006742 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006743 }
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07006744 mInteractiveTimer = new StopwatchTimer(null, -10, null, mOnBatteryTimeBase);
6745 mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase);
6746 mDeviceIdleModeEnabledTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006747 mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006748 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase);
Wink Saville52840902011-02-18 12:40:47 -08006749 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006750 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null,
6751 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006752 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006753 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006754 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006755 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null,
6756 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006757 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006758 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006759 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6760 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006761 }
Adam Lesinski33dac552015-03-09 15:24:48 -07006762 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
6763 mBluetoothActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6764 mWifiActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6765 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006766 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase);
6767 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006768 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006769 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
6770 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006771 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase);
6772 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006773 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006774 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006775 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07006776 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
6777 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i, null, mOnBatteryTimeBase);
6778 }
6779 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
6780 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i, null,
6781 mOnBatteryTimeBase);
6782 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006783 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006784 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006785 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, null, mOnBatteryTimeBase);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08006786 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006787 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
6788 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07006789 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006790 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006791 long uptime = SystemClock.uptimeMillis() * 1000;
6792 long realtime = SystemClock.elapsedRealtime() * 1000;
6793 initTimes(uptime, realtime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07006794 mStartPlatformVersion = mEndPlatformVersion = Build.ID;
Evan Millar633a1742009-04-02 16:36:33 -07006795 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006796 mDischargeUnplugLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006797 mDischargePlugLevel = -1;
Evan Millar633a1742009-04-02 16:36:33 -07006798 mDischargeCurrentLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006799 mCurrentBatteryLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006800 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006801 clearHistoryLocked();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006802 updateDailyDeadlineLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006803 }
6804
6805 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006806 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07006807 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006808 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07006809 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006810 mExternalSync = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006811 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006812 readFromParcel(p);
6813 }
6814
Adam Lesinskie08af192015-03-25 16:42:59 -07006815 public void setPowerProfile(PowerProfile profile) {
6816 synchronized (this) {
6817 mPowerProfile = profile;
6818 }
6819 }
6820
Dianne Hackborn0d903a82010-09-07 23:51:03 -07006821 public void setCallback(BatteryCallback cb) {
6822 mCallback = cb;
6823 }
6824
Amith Yamasanie43530a2009-08-21 13:11:37 -07006825 public void setNumSpeedSteps(int steps) {
6826 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
6827 }
6828
Amith Yamasanif37447b2009-10-08 18:28:01 -07006829 public void setRadioScanningTimeout(long timeout) {
6830 if (mPhoneSignalScanningTimer != null) {
6831 mPhoneSignalScanningTimer.setTimeout(timeout);
6832 }
6833 }
6834
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006835 public void updateDailyDeadlineLocked() {
6836 // Get the current time.
6837 long currentTime = mDailyStartTime = System.currentTimeMillis();
6838 Calendar calDeadline = Calendar.getInstance();
6839 calDeadline.setTimeInMillis(currentTime);
6840
6841 // Move time up to the next day, ranging from 1am to 3pm.
6842 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1);
6843 calDeadline.set(Calendar.MILLISECOND, 0);
6844 calDeadline.set(Calendar.SECOND, 0);
6845 calDeadline.set(Calendar.MINUTE, 0);
6846 calDeadline.set(Calendar.HOUR_OF_DAY, 1);
6847 mNextMinDailyDeadline = calDeadline.getTimeInMillis();
6848 calDeadline.set(Calendar.HOUR_OF_DAY, 3);
6849 mNextMaxDailyDeadline = calDeadline.getTimeInMillis();
6850 }
6851
6852 public void recordDailyStatsIfNeededLocked(boolean settled) {
6853 long currentTime = System.currentTimeMillis();
6854 if (currentTime >= mNextMaxDailyDeadline) {
6855 recordDailyStatsLocked();
6856 } else if (settled && currentTime >= mNextMinDailyDeadline) {
6857 recordDailyStatsLocked();
6858 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) {
6859 recordDailyStatsLocked();
6860 }
6861 }
6862
6863 public void recordDailyStatsLocked() {
6864 DailyItem item = new DailyItem();
6865 item.mStartTime = mDailyStartTime;
6866 item.mEndTime = System.currentTimeMillis();
6867 boolean hasData = false;
6868 if (mDailyDischargeStepTracker.mNumStepDurations > 0) {
6869 hasData = true;
6870 item.mDischargeSteps = new LevelStepTracker(
6871 mDailyDischargeStepTracker.mNumStepDurations,
6872 mDailyDischargeStepTracker.mStepDurations);
6873 }
6874 if (mDailyChargeStepTracker.mNumStepDurations > 0) {
6875 hasData = true;
6876 item.mChargeSteps = new LevelStepTracker(
6877 mDailyChargeStepTracker.mNumStepDurations,
6878 mDailyChargeStepTracker.mStepDurations);
6879 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006880 if (mDailyPackageChanges != null) {
6881 hasData = true;
6882 item.mPackageChanges = mDailyPackageChanges;
6883 mDailyPackageChanges = null;
6884 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006885 mDailyDischargeStepTracker.init();
6886 mDailyChargeStepTracker.init();
6887 updateDailyDeadlineLocked();
6888
6889 if (hasData) {
6890 mDailyItems.add(item);
6891 while (mDailyItems.size() > MAX_DAILY_ITEMS) {
6892 mDailyItems.remove(0);
6893 }
6894 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
6895 try {
6896 XmlSerializer out = new FastXmlSerializer();
6897 out.setOutput(memStream, "utf-8");
6898 writeDailyItemsLocked(out);
6899 BackgroundThread.getHandler().post(new Runnable() {
6900 @Override
6901 public void run() {
6902 synchronized (mCheckinFile) {
6903 FileOutputStream stream = null;
6904 try {
6905 stream = mDailyFile.startWrite();
6906 memStream.writeTo(stream);
6907 stream.flush();
6908 FileUtils.sync(stream);
6909 stream.close();
6910 mDailyFile.finishWrite(stream);
6911 } catch (IOException e) {
6912 Slog.w("BatteryStats",
6913 "Error writing battery daily items", e);
6914 mDailyFile.failWrite(stream);
6915 }
6916 }
6917 }
6918 });
6919 } catch (IOException e) {
6920 }
6921 }
6922 }
6923
6924 private void writeDailyItemsLocked(XmlSerializer out) throws IOException {
6925 StringBuilder sb = new StringBuilder(64);
6926 out.startDocument(null, true);
6927 out.startTag(null, "daily-items");
6928 for (int i=0; i<mDailyItems.size(); i++) {
6929 final DailyItem dit = mDailyItems.get(i);
6930 out.startTag(null, "item");
6931 out.attribute(null, "start", Long.toString(dit.mStartTime));
6932 out.attribute(null, "end", Long.toString(dit.mEndTime));
6933 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb);
6934 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006935 if (dit.mPackageChanges != null) {
6936 for (int j=0; j<dit.mPackageChanges.size(); j++) {
6937 PackageChange pc = dit.mPackageChanges.get(j);
6938 if (pc.mUpdate) {
6939 out.startTag(null, "upd");
6940 out.attribute(null, "pkg", pc.mPackageName);
6941 out.attribute(null, "ver", Integer.toString(pc.mVersionCode));
6942 out.endTag(null, "upd");
6943 } else {
6944 out.startTag(null, "rem");
6945 out.attribute(null, "pkg", pc.mPackageName);
6946 out.endTag(null, "rem");
6947 }
6948 }
6949 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006950 out.endTag(null, "item");
6951 }
6952 out.endTag(null, "daily-items");
6953 out.endDocument();
6954 }
6955
6956 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps,
6957 StringBuilder tmpBuilder) throws IOException {
6958 if (steps != null) {
6959 out.startTag(null, tag);
6960 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations));
6961 for (int i=0; i<steps.mNumStepDurations; i++) {
6962 out.startTag(null, "s");
6963 tmpBuilder.setLength(0);
6964 steps.encodeEntryAt(i, tmpBuilder);
6965 out.attribute(null, "v", tmpBuilder.toString());
6966 out.endTag(null, "s");
6967 }
6968 out.endTag(null, tag);
6969 }
6970 }
6971
6972 public void readDailyStatsLocked() {
6973 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile());
6974 mDailyItems.clear();
6975 FileInputStream stream;
6976 try {
6977 stream = mDailyFile.openRead();
6978 } catch (FileNotFoundException e) {
6979 return;
6980 }
6981 try {
6982 XmlPullParser parser = Xml.newPullParser();
6983 parser.setInput(stream, null);
6984 readDailyItemsLocked(parser);
6985 } catch (XmlPullParserException e) {
6986 } finally {
6987 try {
6988 stream.close();
6989 } catch (IOException e) {
6990 }
6991 }
6992 }
6993
6994 private void readDailyItemsLocked(XmlPullParser parser) {
6995 try {
6996 int type;
6997 while ((type = parser.next()) != XmlPullParser.START_TAG
6998 && type != XmlPullParser.END_DOCUMENT) {
6999 ;
7000 }
7001
7002 if (type != XmlPullParser.START_TAG) {
7003 throw new IllegalStateException("no start tag found");
7004 }
7005
7006 int outerDepth = parser.getDepth();
7007 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
7008 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
7009 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
7010 continue;
7011 }
7012
7013 String tagName = parser.getName();
7014 if (tagName.equals("item")) {
7015 readDailyItemTagLocked(parser);
7016 } else {
7017 Slog.w(TAG, "Unknown element under <daily-items>: "
7018 + parser.getName());
7019 XmlUtils.skipCurrentTag(parser);
7020 }
7021 }
7022
7023 } catch (IllegalStateException e) {
7024 Slog.w(TAG, "Failed parsing daily " + e);
7025 } catch (NullPointerException e) {
7026 Slog.w(TAG, "Failed parsing daily " + e);
7027 } catch (NumberFormatException e) {
7028 Slog.w(TAG, "Failed parsing daily " + e);
7029 } catch (XmlPullParserException e) {
7030 Slog.w(TAG, "Failed parsing daily " + e);
7031 } catch (IOException e) {
7032 Slog.w(TAG, "Failed parsing daily " + e);
7033 } catch (IndexOutOfBoundsException e) {
7034 Slog.w(TAG, "Failed parsing daily " + e);
7035 }
7036 }
7037
7038 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException,
7039 XmlPullParserException, IOException {
7040 DailyItem dit = new DailyItem();
7041 String attr = parser.getAttributeValue(null, "start");
7042 if (attr != null) {
7043 dit.mStartTime = Long.parseLong(attr);
7044 }
7045 attr = parser.getAttributeValue(null, "end");
7046 if (attr != null) {
7047 dit.mEndTime = Long.parseLong(attr);
7048 }
7049 int outerDepth = parser.getDepth();
7050 int type;
7051 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
7052 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
7053 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
7054 continue;
7055 }
7056
7057 String tagName = parser.getName();
7058 if (tagName.equals("dis")) {
7059 readDailyItemTagDetailsLocked(parser, dit, false, "dis");
7060 } else if (tagName.equals("chg")) {
7061 readDailyItemTagDetailsLocked(parser, dit, true, "chg");
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007062 } else if (tagName.equals("upd")) {
7063 if (dit.mPackageChanges == null) {
7064 dit.mPackageChanges = new ArrayList<>();
7065 }
7066 PackageChange pc = new PackageChange();
7067 pc.mUpdate = true;
7068 pc.mPackageName = parser.getAttributeValue(null, "pkg");
7069 String verStr = parser.getAttributeValue(null, "ver");
7070 pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0;
7071 dit.mPackageChanges.add(pc);
7072 XmlUtils.skipCurrentTag(parser);
7073 } else if (tagName.equals("rem")) {
7074 if (dit.mPackageChanges == null) {
7075 dit.mPackageChanges = new ArrayList<>();
7076 }
7077 PackageChange pc = new PackageChange();
7078 pc.mUpdate = false;
7079 pc.mPackageName = parser.getAttributeValue(null, "pkg");
7080 dit.mPackageChanges.add(pc);
7081 XmlUtils.skipCurrentTag(parser);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007082 } else {
7083 Slog.w(TAG, "Unknown element under <item>: "
7084 + parser.getName());
7085 XmlUtils.skipCurrentTag(parser);
7086 }
7087 }
7088 mDailyItems.add(dit);
7089 }
7090
7091 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge,
7092 String tag)
7093 throws NumberFormatException, XmlPullParserException, IOException {
7094 final String numAttr = parser.getAttributeValue(null, "n");
7095 if (numAttr == null) {
7096 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription());
7097 XmlUtils.skipCurrentTag(parser);
7098 return;
7099 }
7100 final int num = Integer.parseInt(numAttr);
7101 LevelStepTracker steps = new LevelStepTracker(num);
7102 if (isCharge) {
7103 dit.mChargeSteps = steps;
7104 } else {
7105 dit.mDischargeSteps = steps;
7106 }
7107 int i = 0;
7108 int outerDepth = parser.getDepth();
7109 int type;
7110 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
7111 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
7112 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
7113 continue;
7114 }
7115
7116 String tagName = parser.getName();
7117 if ("s".equals(tagName)) {
7118 if (i < num) {
7119 String valueAttr = parser.getAttributeValue(null, "v");
7120 if (valueAttr != null) {
7121 steps.decodeEntryAt(i, valueAttr);
7122 i++;
7123 }
7124 }
7125 } else {
7126 Slog.w(TAG, "Unknown element under <" + tag + ">: "
7127 + parser.getName());
7128 XmlUtils.skipCurrentTag(parser);
7129 }
7130 }
7131 steps.mNumStepDurations = i;
7132 }
7133
7134 @Override
7135 public DailyItem getDailyItemLocked(int daysAgo) {
7136 int index = mDailyItems.size()-1-daysAgo;
7137 return index >= 0 ? mDailyItems.get(index) : null;
7138 }
7139
7140 @Override
7141 public long getCurrentDailyStartTime() {
7142 return mDailyStartTime;
7143 }
7144
7145 @Override
7146 public long getNextMinDailyDeadline() {
7147 return mNextMinDailyDeadline;
7148 }
7149
7150 @Override
7151 public long getNextMaxDailyDeadline() {
7152 return mNextMaxDailyDeadline;
7153 }
7154
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007155 @Override
7156 public boolean startIteratingOldHistoryLocked() {
7157 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
7158 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007159 if ((mHistoryIterator = mHistory) == null) {
7160 return false;
7161 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007162 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007163 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007164 mReadOverflow = false;
7165 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007166 return true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007167 }
7168
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007169 @Override
7170 public boolean getNextOldHistoryLocked(HistoryItem out) {
7171 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
7172 if (!end) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007173 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007174 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007175 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007176 HistoryItem cur = mHistoryIterator;
7177 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007178 if (!mReadOverflow && !end) {
7179 Slog.w(TAG, "Old history ends before new history!");
7180 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007181 return false;
7182 }
7183 out.setTo(cur);
7184 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007185 if (!mReadOverflow) {
7186 if (end) {
7187 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007188 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn8c841092013-06-24 13:46:13 -07007189 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007190 pw.println("Histories differ!");
7191 pw.println("Old history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007192 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007193 pw.println("New history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007194 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false,
7195 true);
Dianne Hackborn8c841092013-06-24 13:46:13 -07007196 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007197 }
7198 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007199 return true;
7200 }
7201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007202 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007203 public void finishIteratingOldHistoryLocked() {
7204 mIteratingHistory = false;
7205 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007206 mHistoryIterator = null;
7207 }
7208
7209 public int getHistoryTotalSize() {
7210 return MAX_HISTORY_BUFFER;
7211 }
7212
7213 public int getHistoryUsedSize() {
7214 return mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007215 }
7216
7217 @Override
7218 public boolean startIteratingHistoryLocked() {
7219 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
7220 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007221 if (mHistoryBuffer.dataSize() <= 0) {
7222 return false;
7223 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007224 mHistoryBuffer.setDataPosition(0);
7225 mReadOverflow = false;
7226 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007227 mReadHistoryStrings = new String[mHistoryTagPool.size()];
7228 mReadHistoryUids = new int[mHistoryTagPool.size()];
7229 mReadHistoryChars = 0;
7230 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
7231 final HistoryTag tag = ent.getKey();
7232 final int idx = ent.getValue();
7233 mReadHistoryStrings[idx] = tag.string;
7234 mReadHistoryUids[idx] = tag.uid;
7235 mReadHistoryChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08007236 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007237 return true;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007238 }
7239
7240 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08007241 public int getHistoryStringPoolSize() {
7242 return mReadHistoryStrings.length;
7243 }
7244
7245 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007246 public int getHistoryStringPoolBytes() {
7247 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
7248 // Each string character is 2 bytes.
7249 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
7250 }
7251
7252 @Override
7253 public String getHistoryTagPoolString(int index) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08007254 return mReadHistoryStrings[index];
7255 }
7256
7257 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007258 public int getHistoryTagPoolUid(int index) {
7259 return mReadHistoryUids[index];
7260 }
7261
7262 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007263 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007264 final int pos = mHistoryBuffer.dataPosition();
7265 if (pos == 0) {
7266 out.clear();
7267 }
7268 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007269 if (end) {
7270 return false;
7271 }
7272
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007273 final long lastRealtime = out.time;
7274 final long lastWalltime = out.currentTime;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007275 readHistoryDelta(mHistoryBuffer, out);
Dianne Hackborn37de0982014-05-09 09:32:18 -07007276 if (out.cmd != HistoryItem.CMD_CURRENT_TIME
7277 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007278 out.currentTime = lastWalltime + (out.time - lastRealtime);
7279 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007280 return true;
7281 }
7282
7283 @Override
7284 public void finishIteratingHistoryLocked() {
7285 mIteratingHistory = false;
7286 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn099bc622014-01-22 13:39:16 -08007287 mReadHistoryStrings = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007288 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007289
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007290 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07007291 public long getHistoryBaseTime() {
7292 return mHistoryBaseTime;
7293 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007294
Dianne Hackbornb5e31652010-09-07 12:13:55 -07007295 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007296 public int getStartCount() {
7297 return mStartCount;
7298 }
7299
7300 public boolean isOnBattery() {
7301 return mOnBattery;
7302 }
7303
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007304 public boolean isCharging() {
7305 return mCharging;
7306 }
7307
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007308 public boolean isScreenOn() {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007309 return mScreenState == Display.STATE_ON;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007310 }
7311
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007312 void initTimes(long uptime, long realtime) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007313 mStartClockTime = System.currentTimeMillis();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007314 mOnBatteryTimeBase.init(uptime, realtime);
7315 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
Dianne Hackborn4590e522014-03-24 13:36:46 -07007316 mRealtime = 0;
7317 mUptime = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007318 mRealtimeStart = realtime;
Dianne Hackborn4590e522014-03-24 13:36:46 -07007319 mUptimeStart = uptime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007320 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007321
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007322 void initDischarge() {
7323 mLowDischargeAmountSinceCharge = 0;
7324 mHighDischargeAmountSinceCharge = 0;
7325 mDischargeAmountScreenOn = 0;
7326 mDischargeAmountScreenOnSinceCharge = 0;
7327 mDischargeAmountScreenOff = 0;
7328 mDischargeAmountScreenOffSinceCharge = 0;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007329 mDischargeStepTracker.init();
7330 mChargeStepTracker.init();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007331 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007332
7333 public void resetAllStatsCmdLocked() {
7334 resetAllStatsLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07007335 final long mSecUptime = SystemClock.uptimeMillis();
7336 long uptime = mSecUptime * 1000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007337 long mSecRealtime = SystemClock.elapsedRealtime();
7338 long realtime = mSecRealtime * 1000;
7339 mDischargeStartLevel = mHistoryCur.batteryLevel;
7340 pullPendingStateUpdatesLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07007341 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007342 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
7343 = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007344 mOnBatteryTimeBase.reset(uptime, realtime);
7345 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
7346 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007347 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007348 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
7349 mDischargeScreenOffUnplugLevel = 0;
7350 } else {
7351 mDischargeScreenOnUnplugLevel = 0;
7352 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
7353 }
7354 mDischargeAmountScreenOn = 0;
7355 mDischargeAmountScreenOff = 0;
7356 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07007357 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007358 }
7359
7360 private void resetAllStatsLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007361 mStartCount = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007362 initTimes(SystemClock.uptimeMillis() * 1000, SystemClock.elapsedRealtime() * 1000);
7363 mScreenOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007364 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007365 mScreenBrightnessTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007366 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007367 mInteractiveTimer.reset(false);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07007368 mPowerSaveModeEnabledTimer.reset(false);
7369 mDeviceIdleModeEnabledTimer.reset(false);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007370 mDeviceIdlingTimer.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007371 mPhoneOnTimer.reset(false);
7372 mAudioOnTimer.reset(false);
7373 mVideoOnTimer.reset(false);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07007374 mFlashlightOnTimer.reset(false);
Wink Saville52840902011-02-18 12:40:47 -08007375 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007376 mPhoneSignalStrengthsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007377 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007378 mPhoneSignalScanningTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007379 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007380 mPhoneDataConnectionsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007381 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007382 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007383 mNetworkByteActivityCounters[i].reset(false);
7384 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007385 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007386 mMobileRadioActiveTimer.reset(false);
7387 mMobileRadioActivePerAppTimer.reset(false);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007388 mMobileRadioActiveAdjustedTime.reset(false);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007389 mMobileRadioActiveUnknownTime.reset(false);
7390 mMobileRadioActiveUnknownCount.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007391 mWifiOnTimer.reset(false);
7392 mGlobalWifiRunningTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007393 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007394 mWifiStateTimer[i].reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007395 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07007396 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
7397 mWifiSupplStateTimer[i].reset(false);
7398 }
7399 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
7400 mWifiSignalStrengthsTimer[i].reset(false);
7401 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007402 mBluetoothOnTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007403 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007404 mBluetoothStateTimer[i].reset(false);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007405 }
Adam Lesinski33dac552015-03-09 15:24:48 -07007406 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
7407 mBluetoothActivityCounters[i].reset(false);
7408 mWifiActivityCounters[i].reset(false);
7409 }
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007410 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007411
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007412 for (int i=0; i<mUidStats.size(); i++) {
7413 if (mUidStats.valueAt(i).reset()) {
7414 mUidStats.remove(mUidStats.keyAt(i));
7415 i--;
7416 }
7417 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007418
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007419 if (mKernelWakelockStats.size() > 0) {
7420 for (SamplingTimer timer : mKernelWakelockStats.values()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007421 mOnBatteryScreenOffTimeBase.remove(timer);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007422 }
7423 mKernelWakelockStats.clear();
7424 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007425
7426 if (mWakeupReasonStats.size() > 0) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07007427 for (SamplingTimer timer : mWakeupReasonStats.values()) {
7428 mOnBatteryTimeBase.remove(timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007429 }
7430 mWakeupReasonStats.clear();
7431 }
7432
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007433 mLastHistoryStepDetails = null;
7434 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0;
7435 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0;
7436 mLastStepCpuUserTime = mCurStepCpuUserTime = 0;
7437 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0;
7438 mLastStepStatUserTime = mCurStepStatUserTime = 0;
7439 mLastStepStatSystemTime = mCurStepStatSystemTime = 0;
7440 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0;
7441 mLastStepStatIrqTime = mCurStepStatIrqTime = 0;
7442 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0;
7443 mLastStepStatIdleTime = mCurStepStatIdleTime = 0;
7444
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007445 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007446
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007447 clearHistoryLocked();
7448 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007449
Dianne Hackborn40c87252014-03-19 16:55:40 -07007450 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007451 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007452 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) {
7453 // Not recording process starts/stops.
7454 continue;
7455 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07007456 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007457 if (active == null) {
7458 continue;
7459 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07007460 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
7461 SparseIntArray uids = ent.getValue();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007462 for (int j=0; j<uids.size(); j++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07007463 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
7464 uids.keyAt(j));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007465 }
7466 }
7467 }
7468 }
7469
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007470 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007471 if (oldScreenOn) {
7472 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
7473 if (diff > 0) {
7474 mDischargeAmountScreenOn += diff;
7475 mDischargeAmountScreenOnSinceCharge += diff;
7476 }
7477 } else {
7478 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
7479 if (diff > 0) {
7480 mDischargeAmountScreenOff += diff;
7481 mDischargeAmountScreenOffSinceCharge += diff;
7482 }
7483 }
7484 if (newScreenOn) {
7485 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
7486 mDischargeScreenOffUnplugLevel = 0;
7487 } else {
7488 mDischargeScreenOnUnplugLevel = 0;
7489 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
7490 }
7491 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007492
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007493 public void pullPendingStateUpdatesLocked() {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08007494 if (mOnBatteryInternal) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007495 final boolean screenOn = mScreenState == Display.STATE_ON;
7496 updateDischargeScreenLevelsLocked(screenOn, screenOn);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08007497 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007498 }
7499
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007500 private String[] mMobileIfaces = EmptyArray.STRING;
7501 private String[] mWifiIfaces = EmptyArray.STRING;
7502
7503 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
7504
7505 private static final int NETWORK_STATS_LAST = 0;
7506 private static final int NETWORK_STATS_NEXT = 1;
7507 private static final int NETWORK_STATS_DELTA = 2;
7508
7509 private final NetworkStats[] mMobileNetworkStats = new NetworkStats[] {
7510 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7511 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7512 new NetworkStats(SystemClock.elapsedRealtime(), 50)
7513 };
7514
7515 private final NetworkStats[] mWifiNetworkStats = new NetworkStats[] {
7516 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7517 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7518 new NetworkStats(SystemClock.elapsedRealtime(), 50)
7519 };
7520
7521 /**
7522 * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer
7523 * as a buffer of NetworkStats objects to cycle through when computing deltas.
7524 */
7525 private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces,
7526 NetworkStats[] networkStatsBuffer)
7527 throws IOException {
7528 if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED,
7529 false)) {
7530 return null;
7531 }
7532
7533 final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL,
7534 ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]);
7535 networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats,
7536 networkStatsBuffer[NETWORK_STATS_LAST], null, null,
7537 networkStatsBuffer[NETWORK_STATS_DELTA]);
7538 networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST];
7539 networkStatsBuffer[NETWORK_STATS_LAST] = stats;
7540 return networkStatsBuffer[NETWORK_STATS_DELTA];
7541 }
7542
7543 /**
7544 * Distribute WiFi energy info and network traffic to apps.
7545 * @param info The energy information from the WiFi controller.
7546 */
7547 public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) {
Adam Lesinskie08af192015-03-25 16:42:59 -07007548 final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
7549 NetworkStats delta = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007550 try {
Adam Lesinskie08af192015-03-25 16:42:59 -07007551 if (!ArrayUtils.isEmpty(mWifiIfaces)) {
7552 delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats);
7553 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007554 } catch (IOException e) {
7555 Slog.wtf(TAG, "Failed to get wifi network stats", e);
7556 return;
7557 }
7558
7559 if (!mOnBatteryInternal) {
7560 return;
7561 }
7562
Adam Lesinskie08af192015-03-25 16:42:59 -07007563 SparseLongArray rxPackets = new SparseLongArray();
7564 SparseLongArray txPackets = new SparseLongArray();
7565 long totalTxPackets = 0;
7566 long totalRxPackets = 0;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007567 if (delta != null) {
7568 final int size = delta.size();
7569 for (int i = 0; i < size; i++) {
7570 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
7571
Adam Lesinskie08af192015-03-25 16:42:59 -07007572 if (DEBUG_ENERGY) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007573 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
Adam Lesinskie08af192015-03-25 16:42:59 -07007574 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
7575 + " txPackets=" + entry.txPackets);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007576 }
7577
7578 if (entry.rxBytes == 0 || entry.txBytes == 0) {
7579 continue;
7580 }
7581
7582 final Uid u = getUidStatsLocked(mapUid(entry.uid));
7583 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
7584 entry.rxPackets);
7585 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
7586 entry.txPackets);
Adam Lesinskie08af192015-03-25 16:42:59 -07007587 rxPackets.put(u.getUid(), entry.rxPackets);
7588 txPackets.put(u.getUid(), entry.txPackets);
7589
7590 // Sum the total number of packets so that the Rx Power and Tx Power can
7591 // be evenly distributed amongst the apps.
7592 totalRxPackets += entry.rxPackets;
7593 totalTxPackets += entry.txPackets;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007594
7595 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
7596 entry.rxBytes);
7597 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
7598 entry.txBytes);
7599 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
7600 entry.rxPackets);
7601 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
7602 entry.txPackets);
7603 }
7604 }
7605
7606 if (info != null) {
Adam Lesinski17390762015-04-10 13:17:47 -07007607 mHasWifiEnergyReporting = true;
7608
Adam Lesinskie08af192015-03-25 16:42:59 -07007609 // Measured in mAms
7610 final long txTimeMs = info.getControllerTxTimeMillis();
7611 final long rxTimeMs = info.getControllerRxTimeMillis();
7612 final long idleTimeMs = info.getControllerIdleTimeMillis();
7613 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
7614
7615 long leftOverRxTimeMs = rxTimeMs;
7616
7617 if (DEBUG_ENERGY) {
7618 Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
7619 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
7620 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
7621 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
7622 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms");
7623 }
7624
7625 long totalWifiLockTimeMs = 0;
7626 long totalScanTimeMs = 0;
7627
7628 // On the first pass, collect some totals so that we can normalize power
7629 // calculations if we need to.
7630 final int uidStatsSize = mUidStats.size();
7631 for (int i = 0; i < uidStatsSize; i++) {
7632 final Uid uid = mUidStats.valueAt(i);
7633
7634 // Sum the total scan power for all apps.
7635 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
7636 elapsedRealtimeMs * 1000) / 1000;
7637
7638 // Sum the total time holding wifi lock for all apps.
7639 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
7640 elapsedRealtimeMs * 1000) / 1000;
7641 }
7642
7643 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
7644 Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
7645 + rxTimeMs + " ms). Normalizing scan time.");
7646 }
7647
7648 // Actually assign and distribute power usage to apps.
7649 for (int i = 0; i < uidStatsSize; i++) {
7650 final Uid uid = mUidStats.valueAt(i);
7651
7652 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
7653 elapsedRealtimeMs * 1000) / 1000;
7654 if (scanTimeSinceMarkMs > 0) {
7655 // Set the new mark so that next time we get new data since this point.
7656 uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
7657
7658 if (totalScanTimeMs > rxTimeMs) {
7659 // Our total scan time is more than the reported Rx time.
7660 // This is possible because the cost of a scan is approximate.
7661 // Let's normalize the result so that we evenly blame each app
7662 // scanning.
7663 //
7664 // This means that we may have apps that received packets not be blamed
7665 // for this, but this is fine as scans are relatively more expensive.
7666 scanTimeSinceMarkMs = (rxTimeMs * scanTimeSinceMarkMs) / totalScanTimeMs;
7667 }
7668
7669 if (DEBUG_ENERGY) {
7670 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": "
7671 + scanTimeSinceMarkMs + " ms)");
7672 }
7673 uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanTimeSinceMarkMs);
7674 leftOverRxTimeMs -= scanTimeSinceMarkMs;
7675 }
7676
7677 // Distribute evenly the power consumed while Idle to each app holding a WiFi
7678 // lock.
7679 final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
7680 elapsedRealtimeMs * 1000) / 1000;
7681 if (wifiLockTimeSinceMarkMs > 0) {
7682 // Set the new mark so that next time we get new data since this point.
7683 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
7684
7685 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
7686 / totalWifiLockTimeMs;
7687 if (DEBUG_ENERGY) {
7688 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": "
7689 + myIdleTimeMs + " ms");
7690 }
7691 uid.noteWifiControllerActivityLocked(CONTROLLER_IDLE_TIME, myIdleTimeMs);
7692 }
7693 }
7694
7695 if (DEBUG_ENERGY) {
7696 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
7697 }
7698
7699 // Distribute the Tx power appropriately between all apps that transmitted packets.
7700 for (int i = 0; i < txPackets.size(); i++) {
7701 final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
7702 final long myTxTimeMs = (txPackets.valueAt(i) * txTimeMs) / totalTxPackets;
7703 if (DEBUG_ENERGY) {
7704 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
7705 }
7706 uid.noteWifiControllerActivityLocked(CONTROLLER_TX_TIME, myTxTimeMs);
7707 }
7708
7709 // Distribute the remaining Rx power appropriately between all apps that received
7710 // packets.
7711 for (int i = 0; i < rxPackets.size(); i++) {
7712 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i));
7713 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets;
7714 if (DEBUG_ENERGY) {
7715 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
7716 }
7717 uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, myRxTimeMs);
7718 }
7719
7720 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
7721
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007722 // Update WiFi controller stats.
7723 mWifiActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
7724 info.getControllerRxTimeMillis());
7725 mWifiActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
7726 info.getControllerTxTimeMillis());
7727 mWifiActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
7728 info.getControllerIdleTimeMillis());
Adam Lesinskie08af192015-03-25 16:42:59 -07007729
7730 final double powerDrainMaMs;
7731 if (mPowerProfile.getAveragePower(
7732 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) == 0) {
7733 powerDrainMaMs = 0.0;
7734 } else {
7735 powerDrainMaMs = info.getControllerEnergyUsed()
7736 / mPowerProfile.getAveragePower(
7737 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE);
7738 }
7739 mWifiActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked((long) powerDrainMaMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007740 }
7741 }
7742
7743 /**
7744 * Distribute Cell radio energy info and network traffic to apps.
7745 */
Adam Lesinskie08af192015-03-25 16:42:59 -07007746 public void updateMobileRadioStateLocked(final long elapsedRealtimeMs) {
7747 NetworkStats delta = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007748 try {
Adam Lesinskie08af192015-03-25 16:42:59 -07007749 if (!ArrayUtils.isEmpty(mMobileIfaces)) {
7750 delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats);
7751 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007752 } catch (IOException e) {
7753 Slog.wtf(TAG, "Failed to get mobile network stats", e);
7754 return;
7755 }
7756
7757 if (delta == null || !mOnBatteryInternal) {
7758 return;
7759 }
7760
Adam Lesinskie08af192015-03-25 16:42:59 -07007761 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
7762 elapsedRealtimeMs * 1000);
7763 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007764 long totalPackets = delta.getTotalPackets();
7765
7766 final int size = delta.size();
7767 for (int i = 0; i < size; i++) {
7768 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
7769
Adam Lesinskie08af192015-03-25 16:42:59 -07007770 if (entry.rxBytes == 0 || entry.txBytes == 0) {
7771 continue;
7772 }
7773
7774 if (DEBUG_ENERGY) {
7775 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
7776 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
7777 + " txPackets=" + entry.txPackets);
7778 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007779
7780 final Uid u = getUidStatsLocked(mapUid(entry.uid));
7781 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
7782 entry.rxPackets);
7783 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
7784 entry.txPackets);
7785
7786 if (radioTime > 0) {
7787 // Distribute total radio active time in to this app.
7788 long appPackets = entry.rxPackets + entry.txPackets;
7789 long appRadioTime = (radioTime*appPackets)/totalPackets;
7790 u.noteMobileRadioActiveTimeLocked(appRadioTime);
7791 // Remove this app from the totals, so that we don't lose any time
7792 // due to rounding.
7793 radioTime -= appRadioTime;
7794 totalPackets -= appPackets;
7795 }
7796
7797 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
7798 entry.rxBytes);
7799 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
7800 entry.txBytes);
7801 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
7802 entry.rxPackets);
7803 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
7804 entry.txPackets);
7805 }
7806
7807 if (radioTime > 0) {
7808 // Whoops, there is some radio time we can't blame on an app!
7809 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
7810 mMobileRadioActiveUnknownCount.addCountLocked(1);
7811 }
7812 }
7813
7814 /**
7815 * Distribute Bluetooth energy info and network traffic to apps.
7816 * @param info The energy information from the bluetooth controller.
7817 */
7818 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
Adam Lesinskie08af192015-03-25 16:42:59 -07007819 if (info != null && mOnBatteryInternal && false) {
Adam Lesinski17390762015-04-10 13:17:47 -07007820 mHasBluetoothEnergyReporting = true;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007821 mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
7822 info.getControllerRxTimeMillis());
7823 mBluetoothActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
7824 info.getControllerTxTimeMillis());
7825 mBluetoothActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
7826 info.getControllerIdleTimeMillis());
Adam Lesinskie08af192015-03-25 16:42:59 -07007827 mBluetoothActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked(
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007828 info.getControllerEnergyUsed());
7829 }
7830 }
7831
7832 /**
7833 * Read and distribute kernel wake lock use across apps.
7834 */
7835 public void updateKernelWakelocksLocked() {
7836 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
7837 mTmpWakelockStats);
7838 if (wakelockStats == null) {
7839 // Not crashing might make board bringup easier.
7840 Slog.w(TAG, "Couldn't get kernel wake lock stats");
7841 return;
7842 }
7843
7844 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
7845 String name = ent.getKey();
7846 KernelWakelockStats.Entry kws = ent.getValue();
7847
7848 SamplingTimer kwlt = mKernelWakelockStats.get(name);
7849 if (kwlt == null) {
7850 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
7851 true /* track reported val */);
7852 mKernelWakelockStats.put(name, kwlt);
7853 }
7854 kwlt.updateCurrentReportedCount(kws.mCount);
7855 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
7856 kwlt.setUpdateVersion(kws.mVersion);
7857 }
7858
7859 if (wakelockStats.size() != mKernelWakelockStats.size()) {
7860 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
7861 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
7862 SamplingTimer st = ent.getValue();
7863 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
7864 st.setStale();
7865 }
7866 }
7867 }
7868 }
7869
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007870 boolean setChargingLocked(boolean charging) {
7871 if (mCharging != charging) {
7872 mCharging = charging;
7873 if (charging) {
7874 mHistoryCur.states |= HistoryItem.STATE_CHARGING_FLAG;
7875 } else {
7876 mHistoryCur.states &= ~HistoryItem.STATE_CHARGING_FLAG;
7877 }
7878 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING);
7879 return true;
7880 }
7881 return false;
7882 }
7883
Dianne Hackborn40c87252014-03-19 16:55:40 -07007884 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
7885 final int oldStatus, final int level) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007886 boolean doWrite = false;
7887 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
7888 m.arg1 = onBattery ? 1 : 0;
7889 mHandler.sendMessage(m);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007890
Dianne Hackborn40c87252014-03-19 16:55:40 -07007891 final long uptime = mSecUptime * 1000;
7892 final long realtime = mSecRealtime * 1000;
Jeff Browne95c3cd2014-05-02 16:59:26 -07007893 final boolean screenOn = mScreenState == Display.STATE_ON;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007894 if (onBattery) {
7895 // We will reset our status if we are unplugging after the
7896 // battery was last full, or the level is at 100, or
7897 // we have gone through a significant charge (from a very low
7898 // level to a now very high level).
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007899 boolean reset = false;
Dianne Hackborn9a755432014-05-15 17:05:22 -07007900 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007901 || level >= 90
Dianne Hackbornfb3809c2014-09-29 18:31:22 -07007902 || (mDischargeCurrentLevel < 20 && level >= 80)
7903 || (getHighDischargeAmountSinceCharge() >= 200
7904 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -07007905 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
Dianne Hackbornfb3809c2014-09-29 18:31:22 -07007906 + " dischargeLevel=" + mDischargeCurrentLevel
Dianne Hackborn73d6a822014-09-29 10:52:47 -07007907 + " lowAmount=" + getLowDischargeAmountSinceCharge()
7908 + " highAmount=" + getHighDischargeAmountSinceCharge());
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007909 // Before we write, collect a snapshot of the final aggregated
7910 // stats to be reported in the next checkin. Only do this if we have
7911 // a sufficient amount of data to make it interesting.
7912 if (getLowDischargeAmountSinceCharge() >= 20) {
7913 final Parcel parcel = Parcel.obtain();
7914 writeSummaryToParcel(parcel, true);
7915 BackgroundThread.getHandler().post(new Runnable() {
7916 @Override public void run() {
7917 synchronized (mCheckinFile) {
7918 FileOutputStream stream = null;
7919 try {
7920 stream = mCheckinFile.startWrite();
7921 stream.write(parcel.marshall());
7922 stream.flush();
7923 FileUtils.sync(stream);
7924 stream.close();
7925 mCheckinFile.finishWrite(stream);
7926 } catch (IOException e) {
7927 Slog.w("BatteryStats",
7928 "Error writing checkin battery statistics", e);
7929 mCheckinFile.failWrite(stream);
7930 } finally {
7931 parcel.recycle();
7932 }
7933 }
7934 }
7935 });
7936 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007937 doWrite = true;
7938 resetAllStatsLocked();
7939 mDischargeStartLevel = level;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007940 reset = true;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007941 mDischargeStepTracker.init();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007942 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007943 if (mCharging) {
7944 setChargingLocked(false);
7945 }
7946 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007947 mOnBattery = mOnBatteryInternal = true;
Dianne Hackborn260c5022014-04-29 11:23:16 -07007948 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07007949 mMinDischargeStepLevel = level;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007950 mDischargeStepTracker.clearTime();
7951 mDailyDischargeStepTracker.clearTime();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007952 mInitStepMode = mCurStepMode;
7953 mModStepMode = 0;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007954 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007955 mHistoryCur.batteryLevel = (byte)level;
7956 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
7957 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
7958 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007959 if (reset) {
7960 mRecordingHistory = true;
7961 startRecordingHistory(mSecRealtime, mSecUptime, reset);
7962 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07007963 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007964 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
Jeff Browne95c3cd2014-05-02 16:59:26 -07007965 if (screenOn) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007966 mDischargeScreenOnUnplugLevel = level;
7967 mDischargeScreenOffUnplugLevel = 0;
7968 } else {
7969 mDischargeScreenOnUnplugLevel = 0;
7970 mDischargeScreenOffUnplugLevel = level;
7971 }
7972 mDischargeAmountScreenOn = 0;
7973 mDischargeAmountScreenOff = 0;
Jeff Browne95c3cd2014-05-02 16:59:26 -07007974 updateTimeBasesLocked(true, !screenOn, uptime, realtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007975 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07007976 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007977 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007978 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007979 mHistoryCur.batteryLevel = (byte)level;
7980 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
7981 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
7982 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07007983 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007984 mDischargeCurrentLevel = mDischargePlugLevel = level;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007985 if (level < mDischargeUnplugLevel) {
7986 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
7987 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
7988 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007989 updateDischargeScreenLevelsLocked(screenOn, screenOn);
7990 updateTimeBasesLocked(false, !screenOn, uptime, realtime);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007991 mChargeStepTracker.init();
Dianne Hackborn260c5022014-04-29 11:23:16 -07007992 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07007993 mMaxChargeStepLevel = level;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007994 mInitStepMode = mCurStepMode;
7995 mModStepMode = 0;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007996 }
7997 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
7998 if (mFile != null) {
7999 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008000 }
8001 }
8002 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008003
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008004 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
8005 boolean reset) {
8006 mRecordingHistory = true;
8007 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborna7d0d552014-09-12 17:15:52 -07008008 mLastRecordedClockTime = mHistoryCur.currentTime;
8009 mLastRecordedClockRealtime = elapsedRealtimeMs;
Dianne Hackborn37de0982014-05-09 09:32:18 -07008010 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
8011 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008012 mHistoryCur);
8013 mHistoryCur.currentTime = 0;
8014 if (reset) {
8015 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
8016 }
8017 }
8018
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07008019 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs,
8020 final long uptimeMs) {
8021 if (mRecordingHistory) {
8022 mHistoryCur.currentTime = currentTime;
Dianne Hackborna7d0d552014-09-12 17:15:52 -07008023 mLastRecordedClockTime = currentTime;
8024 mLastRecordedClockRealtime = elapsedRealtimeMs;
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07008025 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
8026 mHistoryCur);
8027 mHistoryCur.currentTime = 0;
8028 }
8029 }
8030
Dianne Hackborn29cd7f12015-01-08 10:37:05 -08008031 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
8032 if (mRecordingHistory) {
8033 mHistoryCur.currentTime = System.currentTimeMillis();
8034 mLastRecordedClockTime = mHistoryCur.currentTime;
8035 mLastRecordedClockRealtime = elapsedRealtimeMs;
8036 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN,
8037 mHistoryCur);
8038 mHistoryCur.currentTime = 0;
8039 }
8040 }
8041
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008042 private void scheduleSyncExternalStatsLocked() {
8043 if (mExternalSync != null) {
8044 mExternalSync.scheduleSync();
8045 }
8046 }
8047
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008048 // This should probably be exposed in the API, though it's not critical
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008049 public static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008050
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008051 public void setBatteryStateLocked(int status, int health, int plugType, int level,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008052 int temp, int volt) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008053 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
8054 final long uptime = SystemClock.uptimeMillis();
8055 final long elapsedRealtime = SystemClock.elapsedRealtime();
8056 if (!mHaveBatteryLevel) {
8057 mHaveBatteryLevel = true;
8058 // We start out assuming that the device is plugged in (not
8059 // on battery). If our first report is now that we are indeed
8060 // plugged in, then twiddle our state to correctly reflect that
8061 // since we won't be going through the full setOnBattery().
8062 if (onBattery == mOnBattery) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008063 if (onBattery) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008064 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008065 } else {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008066 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008067 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008068 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008069 // Always start out assuming charging, that will be updated later.
8070 mHistoryCur.states |= HistoryItem.STATE_CHARGING_FLAG;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008071 mHistoryCur.batteryStatus = (byte)status;
8072 mHistoryCur.batteryLevel = (byte)level;
8073 mMaxChargeStepLevel = mMinDischargeStepLevel =
8074 mLastChargeStepLevel = mLastDischargeStepLevel = level;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008075 mLastChargingStateLevel = level;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008076 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
8077 recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
8078 }
8079 int oldStatus = mHistoryCur.batteryStatus;
8080 if (onBattery) {
8081 mDischargeCurrentLevel = level;
8082 if (!mRecordingHistory) {
8083 mRecordingHistory = true;
8084 startRecordingHistory(elapsedRealtime, uptime, true);
8085 }
8086 } else if (level < 96) {
8087 if (!mRecordingHistory) {
8088 mRecordingHistory = true;
8089 startRecordingHistory(elapsedRealtime, uptime, true);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008090 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008091 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008092 mCurrentBatteryLevel = level;
8093 if (mDischargePlugLevel < 0) {
8094 mDischargePlugLevel = level;
Marco Nelissend8593312009-04-30 14:45:06 -07008095 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008096 if (onBattery != mOnBattery) {
8097 mHistoryCur.batteryLevel = (byte)level;
8098 mHistoryCur.batteryStatus = (byte)status;
8099 mHistoryCur.batteryHealth = (byte)health;
8100 mHistoryCur.batteryPlugType = (byte)plugType;
8101 mHistoryCur.batteryTemperature = (short)temp;
8102 mHistoryCur.batteryVoltage = (char)volt;
8103 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
8104 } else {
8105 boolean changed = false;
8106 if (mHistoryCur.batteryLevel != level) {
8107 mHistoryCur.batteryLevel = (byte)level;
8108 changed = true;
Marco Nelissend8593312009-04-30 14:45:06 -07008109
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008110 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
8111 // which will pull external stats.
8112 scheduleSyncExternalStatsLocked();
Evan Millarc64edde2009-04-18 12:26:32 -07008113 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008114 if (mHistoryCur.batteryStatus != status) {
8115 mHistoryCur.batteryStatus = (byte)status;
8116 changed = true;
8117 }
8118 if (mHistoryCur.batteryHealth != health) {
8119 mHistoryCur.batteryHealth = (byte)health;
8120 changed = true;
8121 }
8122 if (mHistoryCur.batteryPlugType != plugType) {
8123 mHistoryCur.batteryPlugType = (byte)plugType;
8124 changed = true;
8125 }
8126 if (temp >= (mHistoryCur.batteryTemperature+10)
8127 || temp <= (mHistoryCur.batteryTemperature-10)) {
8128 mHistoryCur.batteryTemperature = (short)temp;
8129 changed = true;
8130 }
8131 if (volt > (mHistoryCur.batteryVoltage+20)
8132 || volt < (mHistoryCur.batteryVoltage-20)) {
8133 mHistoryCur.batteryVoltage = (char)volt;
8134 changed = true;
8135 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008136 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
8137 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
8138 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
8139 if (onBattery) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008140 changed |= setChargingLocked(false);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008141 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
8142 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
8143 modeBits, elapsedRealtime);
8144 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
8145 modeBits, elapsedRealtime);
8146 mLastDischargeStepLevel = level;
8147 mMinDischargeStepLevel = level;
8148 mInitStepMode = mCurStepMode;
8149 mModStepMode = 0;
8150 }
8151 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008152 if (level >= 90) {
8153 // If the battery level is at least 90%, always consider the device to be
8154 // charging even if it happens to go down a level.
8155 changed |= setChargingLocked(true);
8156 mLastChargeStepLevel = level;
8157 } if (!mCharging) {
8158 if (mLastChargeStepLevel < level) {
8159 // We have not reporting that we are charging, but the level has now
8160 // gone up, so consider the state to be charging.
8161 changed |= setChargingLocked(true);
8162 mLastChargeStepLevel = level;
8163 }
8164 } else {
8165 if (mLastChargeStepLevel > level) {
8166 // We had reported that the device was charging, but here we are with
8167 // power connected and the level going down. Looks like the current
8168 // power supplied isn't enough, so consider the device to now be
8169 // discharging.
8170 changed |= setChargingLocked(false);
8171 mLastChargeStepLevel = level;
8172 }
8173 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008174 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
8175 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
8176 modeBits, elapsedRealtime);
8177 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
8178 modeBits, elapsedRealtime);
8179 mLastChargeStepLevel = level;
8180 mMaxChargeStepLevel = level;
8181 mInitStepMode = mCurStepMode;
8182 mModStepMode = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07008183 }
8184 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07008185 if (changed) {
8186 addHistoryRecordLocked(elapsedRealtime, uptime);
8187 }
Evan Millarc64edde2009-04-18 12:26:32 -07008188 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008189 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
8190 // We don't record history while we are plugged in and fully charged.
8191 // The next time we are unplugged, history will be cleared.
8192 mRecordingHistory = DEBUG;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08008193 }
Adam Lesinski33dac552015-03-09 15:24:48 -07008194 }
8195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008196 public long getAwakeTimeBattery() {
8197 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
8198 }
8199
8200 public long getAwakeTimePlugged() {
8201 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
8202 }
8203
8204 @Override
8205 public long computeUptime(long curTime, int which) {
8206 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008207 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008208 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07008209 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008210 }
8211 return 0;
8212 }
8213
8214 @Override
8215 public long computeRealtime(long curTime, int which) {
8216 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008217 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008218 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07008219 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008220 }
8221 return 0;
8222 }
8223
8224 @Override
8225 public long computeBatteryUptime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008226 return mOnBatteryTimeBase.computeUptime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008227 }
8228
8229 @Override
8230 public long computeBatteryRealtime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008231 return mOnBatteryTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008232 }
8233
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008234 @Override
8235 public long computeBatteryScreenOffUptime(long curTime, int which) {
8236 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
8237 }
8238
8239 @Override
8240 public long computeBatteryScreenOffRealtime(long curTime, int which) {
8241 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008242 }
8243
Dianne Hackborn260c5022014-04-29 11:23:16 -07008244 private long computeTimePerLevel(long[] steps, int numSteps) {
8245 // For now we'll do a simple average across all steps.
8246 if (numSteps <= 0) {
8247 return -1;
8248 }
8249 long total = 0;
8250 for (int i=0; i<numSteps; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008251 total += steps[i] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008252 }
8253 return total / numSteps;
8254 /*
8255 long[] buckets = new long[numSteps];
8256 int numBuckets = 0;
8257 int numToAverage = 4;
8258 int i = 0;
8259 while (i < numSteps) {
8260 long totalTime = 0;
8261 int num = 0;
8262 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008263 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008264 num++;
8265 }
8266 buckets[numBuckets] = totalTime / num;
8267 numBuckets++;
8268 numToAverage *= 2;
8269 i += num;
8270 }
8271 if (numBuckets < 1) {
8272 return -1;
8273 }
8274 long averageTime = buckets[numBuckets-1];
8275 for (i=numBuckets-2; i>=0; i--) {
8276 averageTime = (averageTime + buckets[i]) / 2;
8277 }
8278 return averageTime;
8279 */
8280 }
8281
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008282 @Override
8283 public long computeBatteryTimeRemaining(long curTime) {
8284 if (!mOnBattery) {
8285 return -1;
8286 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07008287 /* Simple implementation just looks at the average discharge per level across the
8288 entire sample period.
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008289 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2;
8290 if (discharge < 2) {
8291 return -1;
8292 }
8293 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED);
8294 if (duration < 1000*1000) {
8295 return -1;
8296 }
8297 long usPerLevel = duration/discharge;
8298 return usPerLevel * mCurrentBatteryLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008299 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008300 if (mDischargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008301 return -1;
8302 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008303 long msPerLevel = mDischargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -07008304 if (msPerLevel <= 0) {
8305 return -1;
8306 }
8307 return (msPerLevel * mCurrentBatteryLevel) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008308 }
8309
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008310 @Override
8311 public LevelStepTracker getDischargeLevelStepTracker() {
8312 return mDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008313 }
8314
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008315 @Override
8316 public LevelStepTracker getDailyDischargeLevelStepTracker() {
8317 return mDailyDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008318 }
8319
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008320 @Override
8321 public long computeChargeTimeRemaining(long curTime) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008322 if (mOnBattery) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008323 // Not yet working.
8324 return -1;
8325 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07008326 /* Broken
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008327 int curLevel = mCurrentBatteryLevel;
8328 int plugLevel = mDischargePlugLevel;
8329 if (plugLevel < 0 || curLevel < (plugLevel+1)) {
8330 return -1;
8331 }
8332 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED);
8333 if (duration < 1000*1000) {
8334 return -1;
8335 }
8336 long usPerLevel = duration/(curLevel-plugLevel);
8337 return usPerLevel * (100-curLevel);
Dianne Hackborn260c5022014-04-29 11:23:16 -07008338 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008339 if (mChargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008340 return -1;
8341 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008342 long msPerLevel = mChargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -07008343 if (msPerLevel <= 0) {
8344 return -1;
8345 }
8346 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008347 }
8348
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008349 @Override
8350 public LevelStepTracker getChargeLevelStepTracker() {
8351 return mChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008352 }
8353
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008354 @Override
8355 public LevelStepTracker getDailyChargeLevelStepTracker() {
8356 return mDailyChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008357 }
8358
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008359 @Override
8360 public ArrayList<PackageChange> getDailyPackageChanges() {
8361 return mDailyPackageChanges;
8362 }
8363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008364 long getBatteryUptimeLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008365 return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008366 }
8367
8368 @Override
8369 public long getBatteryUptime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008370 return mOnBatteryTimeBase.getUptime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008371 }
8372
8373 @Override
8374 public long getBatteryRealtime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008375 return mOnBatteryTimeBase.getRealtime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008376 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07008377
The Android Open Source Project10592532009-03-18 17:39:46 -07008378 @Override
Evan Millar633a1742009-04-02 16:36:33 -07008379 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07008380 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07008381 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07008382 }
8383 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008384
Evan Millar633a1742009-04-02 16:36:33 -07008385 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008386 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07008387 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008388
The Android Open Source Project10592532009-03-18 17:39:46 -07008389 @Override
Evan Millar633a1742009-04-02 16:36:33 -07008390 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07008391 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07008392 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07008393 }
8394 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008395
Evan Millar633a1742009-04-02 16:36:33 -07008396 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008397 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07008398 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008399
Amith Yamasanie43530a2009-08-21 13:11:37 -07008400 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008401 public int getLowDischargeAmountSinceCharge() {
8402 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008403 int val = mLowDischargeAmountSinceCharge;
8404 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
8405 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
8406 }
8407 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008408 }
8409 }
8410
8411 @Override
8412 public int getHighDischargeAmountSinceCharge() {
8413 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008414 int val = mHighDischargeAmountSinceCharge;
8415 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
8416 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
8417 }
8418 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008419 }
8420 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07008421
8422 @Override
8423 public int getDischargeAmount(int which) {
8424 int dischargeAmount = which == STATS_SINCE_CHARGED
8425 ? getHighDischargeAmountSinceCharge()
8426 : (getDischargeStartLevel() - getDischargeCurrentLevel());
8427 if (dischargeAmount < 0) {
8428 dischargeAmount = 0;
8429 }
8430 return dischargeAmount;
8431 }
8432
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008433 public int getDischargeAmountScreenOn() {
8434 synchronized(this) {
8435 int val = mDischargeAmountScreenOn;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008436 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008437 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
8438 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
8439 }
8440 return val;
8441 }
8442 }
8443
8444 public int getDischargeAmountScreenOnSinceCharge() {
8445 synchronized(this) {
8446 int val = mDischargeAmountScreenOnSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008447 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008448 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
8449 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
8450 }
8451 return val;
8452 }
8453 }
8454
8455 public int getDischargeAmountScreenOff() {
8456 synchronized(this) {
8457 int val = mDischargeAmountScreenOff;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008458 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008459 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
8460 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
8461 }
8462 return val;
8463 }
8464 }
8465
8466 public int getDischargeAmountScreenOffSinceCharge() {
8467 synchronized(this) {
8468 int val = mDischargeAmountScreenOffSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008469 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008470 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
8471 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
8472 }
8473 return val;
8474 }
8475 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008476
8477 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07008478 public int getCpuSpeedSteps() {
8479 return sNumSpeedSteps;
8480 }
8481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008482 /**
8483 * Retrieve the statistics object for a particular uid, creating if needed.
8484 */
8485 public Uid getUidStatsLocked(int uid) {
8486 Uid u = mUidStats.get(uid);
8487 if (u == null) {
8488 u = new Uid(uid);
8489 mUidStats.put(uid, u);
8490 }
8491 return u;
8492 }
8493
8494 /**
8495 * Remove the statistics object for a particular uid.
8496 */
8497 public void removeUidStatsLocked(int uid) {
8498 mUidStats.remove(uid);
8499 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07008500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008501 /**
8502 * Retrieve the statistics object for a particular process, creating
8503 * if needed.
8504 */
8505 public Uid.Proc getProcessStatsLocked(int uid, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008506 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008507 Uid u = getUidStatsLocked(uid);
8508 return u.getProcessStatsLocked(name);
8509 }
8510
8511 /**
8512 * Retrieve the statistics object for a particular process, creating
8513 * if needed.
8514 */
8515 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008516 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008517 Uid u = getUidStatsLocked(uid);
8518 return u.getPackageStatsLocked(pkg);
8519 }
8520
8521 /**
8522 * Retrieve the statistics object for a particular service, creating
8523 * if needed.
8524 */
8525 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008526 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008527 Uid u = getUidStatsLocked(uid);
8528 return u.getServiceStatsLocked(pkg, name);
8529 }
8530
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008531 /**
8532 * Massage data to distribute any reasonable work down to more specific
8533 * owners. Must only be called on a dead BatteryStats object!
8534 */
8535 public void distributeWorkLocked(int which) {
8536 // Aggregate all CPU time associated with WIFI.
8537 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
8538 if (wifiUid != null) {
8539 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
Dianne Hackborn61659e52014-07-09 16:13:01 -07008540 for (int ip=wifiUid.mProcessStats.size()-1; ip>=0; ip--) {
8541 Uid.Proc proc = wifiUid.mProcessStats.valueAt(ip);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008542 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
8543 for (int i=0; i<mUidStats.size(); i++) {
8544 Uid uid = mUidStats.valueAt(i);
8545 if (uid.mUid != Process.WIFI_UID) {
8546 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
8547 if (uidRunningTime > 0) {
8548 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
8549 long time = proc.getUserTime(which);
8550 time = (time*uidRunningTime)/totalRunningTime;
8551 uidProc.mUserTime += time;
8552 proc.mUserTime -= time;
8553 time = proc.getSystemTime(which);
8554 time = (time*uidRunningTime)/totalRunningTime;
8555 uidProc.mSystemTime += time;
8556 proc.mSystemTime -= time;
8557 time = proc.getForegroundTime(which);
8558 time = (time*uidRunningTime)/totalRunningTime;
8559 uidProc.mForegroundTime += time;
8560 proc.mForegroundTime -= time;
8561 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
8562 SamplingCounter sc = proc.mSpeedBins[sb];
8563 if (sc != null) {
8564 time = sc.getCountLocked(which);
8565 time = (time*uidRunningTime)/totalRunningTime;
8566 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
8567 if (uidSc == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008568 uidSc = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008569 uidProc.mSpeedBins[sb] = uidSc;
8570 }
8571 uidSc.mCount.addAndGet((int)time);
8572 sc.mCount.addAndGet((int)-time);
8573 }
8574 }
8575 totalRunningTime -= uidRunningTime;
8576 }
8577 }
8578 }
8579 }
8580 }
8581 }
8582
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008583 public void shutdownLocked() {
Dianne Hackborn29cd7f12015-01-08 10:37:05 -08008584 recordShutdownLocked(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008585 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008586 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008587 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008588
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008589 Parcel mPendingWrite = null;
8590 final ReentrantLock mWriteLock = new ReentrantLock();
8591
8592 public void writeAsyncLocked() {
8593 writeLocked(false);
8594 }
8595
8596 public void writeSyncLocked() {
8597 writeLocked(true);
8598 }
8599
8600 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008601 if (mFile == null) {
8602 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008603 return;
8604 }
8605
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008606 if (mShuttingDown) {
8607 return;
8608 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008609
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008610 Parcel out = Parcel.obtain();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008611 writeSummaryToParcel(out, true);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008612 mLastWriteTime = SystemClock.elapsedRealtime();
8613
8614 if (mPendingWrite != null) {
8615 mPendingWrite.recycle();
8616 }
8617 mPendingWrite = out;
8618
8619 if (sync) {
8620 commitPendingDataToDisk();
8621 } else {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008622 BackgroundThread.getHandler().post(new Runnable() {
8623 @Override public void run() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008624 commitPendingDataToDisk();
8625 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008626 });
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008627 }
8628 }
8629
8630 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07008631 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008632 synchronized (this) {
8633 next = mPendingWrite;
8634 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07008635 if (next == null) {
8636 return;
8637 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008638
8639 mWriteLock.lock();
8640 }
8641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008642 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008643 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008644 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008645 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07008646 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008647 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008648 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008649 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008650 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008651 mFile.rollback();
8652 } finally {
8653 next.recycle();
8654 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07008655 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008656 }
8657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008658 public void readLocked() {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008659 if (mDailyFile != null) {
8660 readDailyStatsLocked();
8661 }
8662
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008663 if (mFile == null) {
8664 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008665 return;
8666 }
8667
8668 mUidStats.clear();
8669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008670 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008671 File file = mFile.chooseForRead();
8672 if (!file.exists()) {
8673 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008674 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008675 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008676
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008677 byte[] raw = BatteryStatsHelper.readFully(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008678 Parcel in = Parcel.obtain();
8679 in.unmarshall(raw, 0, raw.length);
8680 in.setDataPosition(0);
8681 stream.close();
8682
8683 readSummaryFromParcel(in);
Dianne Hackborn00e25212014-02-19 10:49:24 -08008684 } catch(Exception e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008685 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008686 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008687
Dianne Hackborncd0e3352014-08-07 17:08:09 -07008688 mEndPlatformVersion = Build.ID;
8689
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008690 if (mHistoryBuffer.dataPosition() > 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008691 mRecordingHistory = true;
Dianne Hackborn40c87252014-03-19 16:55:40 -07008692 final long elapsedRealtime = SystemClock.elapsedRealtime();
8693 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008694 if (USE_OLD_HISTORY) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008695 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008696 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008697 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
8698 startRecordingHistory(elapsedRealtime, uptime, false);
Dianne Hackborne8c88e62011-08-17 19:09:09 -07008699 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008700
8701 recordDailyStatsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008702 }
8703
8704 public int describeContents() {
8705 return 0;
8706 }
8707
Dianne Hackbornae384452011-06-28 12:33:48 -07008708 void readHistory(Parcel in, boolean andOldHistory) {
8709 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008710
8711 mHistoryBuffer.setDataSize(0);
8712 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008713 mHistoryTagPool.clear();
8714 mNextHistoryTagIdx = 0;
8715 mNumHistoryTagChars = 0;
Dianne Hackborn099bc622014-01-22 13:39:16 -08008716
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008717 int numTags = in.readInt();
8718 for (int i=0; i<numTags; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08008719 int idx = in.readInt();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008720 String str = in.readString();
8721 int uid = in.readInt();
8722 HistoryTag tag = new HistoryTag();
8723 tag.string = str;
8724 tag.uid = uid;
8725 tag.poolIdx = idx;
8726 mHistoryTagPool.put(tag, idx);
8727 if (idx >= mNextHistoryTagIdx) {
8728 mNextHistoryTagIdx = idx+1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08008729 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008730 mNumHistoryTagChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08008731 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008732
8733 int bufSize = in.readInt();
8734 int curPos = in.dataPosition();
8735 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
8736 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
8737 } else if ((bufSize&~3) != bufSize) {
8738 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
8739 } else {
8740 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
8741 + " bytes at " + curPos);
8742 mHistoryBuffer.appendFrom(in, curPos, bufSize);
8743 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008744 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008745
Dianne Hackbornae384452011-06-28 12:33:48 -07008746 if (andOldHistory) {
8747 readOldHistory(in);
8748 }
8749
8750 if (DEBUG_HISTORY) {
8751 StringBuilder sb = new StringBuilder(128);
8752 sb.append("****************** OLD mHistoryBaseTime: ");
8753 TimeUtils.formatDuration(mHistoryBaseTime, sb);
8754 Slog.i(TAG, sb.toString());
8755 }
8756 mHistoryBaseTime = historyBaseTime;
8757 if (DEBUG_HISTORY) {
8758 StringBuilder sb = new StringBuilder(128);
8759 sb.append("****************** NEW mHistoryBaseTime: ");
8760 TimeUtils.formatDuration(mHistoryBaseTime, sb);
8761 Slog.i(TAG, sb.toString());
8762 }
8763
8764 // We are just arbitrarily going to insert 1 minute from the sample of
8765 // the last run until samples in this run.
8766 if (mHistoryBaseTime > 0) {
8767 long oldnow = SystemClock.elapsedRealtime();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008768 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1;
Dianne Hackbornae384452011-06-28 12:33:48 -07008769 if (DEBUG_HISTORY) {
8770 StringBuilder sb = new StringBuilder(128);
8771 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
8772 TimeUtils.formatDuration(mHistoryBaseTime, sb);
8773 Slog.i(TAG, sb.toString());
8774 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07008775 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008776 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008777
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008778 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07008779 if (!USE_OLD_HISTORY) {
8780 return;
8781 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008782 mHistory = mHistoryEnd = mHistoryCache = null;
8783 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07008784 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008785 HistoryItem rec = new HistoryItem(time, in);
8786 addHistoryRecordLocked(rec);
8787 }
8788 }
8789
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008790 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) {
Dianne Hackbornae384452011-06-28 12:33:48 -07008791 if (DEBUG_HISTORY) {
8792 StringBuilder sb = new StringBuilder(128);
8793 sb.append("****************** WRITING mHistoryBaseTime: ");
8794 TimeUtils.formatDuration(mHistoryBaseTime, sb);
Dianne Hackborn40c87252014-03-19 16:55:40 -07008795 sb.append(" mLastHistoryElapsedRealtime: ");
8796 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
Dianne Hackbornae384452011-06-28 12:33:48 -07008797 Slog.i(TAG, sb.toString());
8798 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07008799 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008800 if (!inclData) {
8801 out.writeInt(0);
8802 out.writeInt(0);
8803 return;
8804 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008805 out.writeInt(mHistoryTagPool.size());
8806 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
8807 HistoryTag tag = ent.getKey();
Dianne Hackborn099bc622014-01-22 13:39:16 -08008808 out.writeInt(ent.getValue());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008809 out.writeString(tag.string);
8810 out.writeInt(tag.uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08008811 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008812 out.writeInt(mHistoryBuffer.dataSize());
8813 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
8814 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
8815 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07008816
8817 if (andOldHistory) {
8818 writeOldHistory(out);
8819 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008820 }
8821
8822 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07008823 if (!USE_OLD_HISTORY) {
8824 return;
8825 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008826 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008827 while (rec != null) {
8828 if (rec.time >= 0) rec.writeToParcel(out, 0);
8829 rec = rec.next;
8830 }
8831 out.writeLong(-1);
8832 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008833
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008834 public void readSummaryFromParcel(Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008835 final int version = in.readInt();
8836 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008837 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008838 + ", expected " + VERSION + "; erasing old stats");
8839 return;
8840 }
8841
Dianne Hackbornae384452011-06-28 12:33:48 -07008842 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008844 mStartCount = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008845 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008846 mRealtime = in.readLong();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08008847 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07008848 mStartPlatformVersion = in.readString();
8849 mEndPlatformVersion = in.readString();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008850 mOnBatteryTimeBase.readSummaryFromParcel(in);
8851 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008852 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008853 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07008854 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008855 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008856 mLowDischargeAmountSinceCharge = in.readInt();
8857 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008858 mDischargeAmountScreenOnSinceCharge = in.readInt();
8859 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008860 mDischargeStepTracker.readFromParcel(in);
8861 mChargeStepTracker.readFromParcel(in);
8862 mDailyDischargeStepTracker.readFromParcel(in);
8863 mDailyChargeStepTracker.readFromParcel(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008864 int NPKG = in.readInt();
8865 if (NPKG > 0) {
8866 mDailyPackageChanges = new ArrayList<>(NPKG);
8867 while (NPKG > 0) {
8868 NPKG--;
8869 PackageChange pc = new PackageChange();
8870 pc.mPackageName = in.readString();
8871 pc.mUpdate = in.readInt() != 0;
8872 pc.mVersionCode = in.readInt();
8873 mDailyPackageChanges.add(pc);
8874 }
8875 } else {
8876 mDailyPackageChanges = null;
8877 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008878 mDailyStartTime = in.readLong();
8879 mNextMinDailyDeadline = in.readLong();
8880 mNextMaxDailyDeadline = in.readLong();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008882 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008883
Jeff Browne95c3cd2014-05-02 16:59:26 -07008884 mScreenState = Display.STATE_UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008885 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07008886 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
8887 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
8888 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07008889 mInteractive = false;
8890 mInteractiveTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008891 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07008892 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in);
8893 mDeviceIdleModeEnabledTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008894 mDeviceIdlingTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008895 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08008896 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07008897 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
8898 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07008899 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07008900 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
8901 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
8902 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008903 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08008904 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
8905 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008906 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008907 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08008908 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08008909 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008910 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08008911 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
8912 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07008913 mWifiOn = false;
8914 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008915 mGlobalWifiRunning = false;
8916 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08008917 for (int i=0; i<NUM_WIFI_STATES; i++) {
8918 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
8919 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07008920 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
8921 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in);
8922 }
8923 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
8924 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
8925 }
The Android Open Source Project10592532009-03-18 17:39:46 -07008926 mBluetoothOn = false;
8927 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08008928 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
8929 mBluetoothStateTimer[i].readSummaryFromParcelLocked(in);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08008930 }
Adam Lesinski33dac552015-03-09 15:24:48 -07008931
8932 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
8933 mBluetoothActivityCounters[i].readSummaryFromParcelLocked(in);
8934 }
8935
8936 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
8937 mWifiActivityCounters[i].readSummaryFromParcelLocked(in);
8938 }
8939
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008940 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
Dianne Hackbornabc7c492014-06-30 16:57:46 -07008941 mFlashlightOn = false;
8942 mFlashlightOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008943
Evan Millarc64edde2009-04-18 12:26:32 -07008944 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008945 if (NKW > 10000) {
8946 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
8947 return;
8948 }
Evan Millarc64edde2009-04-18 12:26:32 -07008949 for (int ikw = 0; ikw < NKW; ikw++) {
8950 if (in.readInt() != 0) {
8951 String kwltName = in.readString();
8952 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
8953 }
8954 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07008955
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008956 int NWR = in.readInt();
8957 if (NWR > 10000) {
8958 Slog.w(TAG, "File corrupt: too many wakeup reasons " + NWR);
8959 return;
8960 }
8961 for (int iwr = 0; iwr < NWR; iwr++) {
8962 if (in.readInt() != 0) {
8963 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07008964 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008965 }
8966 }
8967
Amith Yamasanie43530a2009-08-21 13:11:37 -07008968 sNumSpeedSteps = in.readInt();
Dianne Hackborn00e25212014-02-19 10:49:24 -08008969 if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) {
8970 throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps);
8971 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07008972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008973 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008974 if (NU > 10000) {
8975 Slog.w(TAG, "File corrupt: too many uids " + NU);
8976 return;
8977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008978 for (int iu = 0; iu < NU; iu++) {
8979 int uid = in.readInt();
8980 Uid u = new Uid(uid);
8981 mUidStats.put(uid, u);
8982
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008983 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008984 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008985 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008986 }
The Android Open Source Project10592532009-03-18 17:39:46 -07008987 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008988 if (in.readInt() != 0) {
8989 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
8990 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07008991 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008992 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07008993 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008994 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07008995 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
8996 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
8997 if (in.readInt() != 0) {
8998 u.makeWifiBatchedScanBin(i, null);
8999 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
9000 }
9001 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07009002 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009003 if (in.readInt() != 0) {
9004 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
9005 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009006 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009007 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009008 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009009 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009010 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
9011 }
9012 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009013 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
9014 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07009015 u.mProcessState = Uid.PROCESS_STATE_NONE;
9016 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
9017 if (in.readInt() != 0) {
9018 u.makeProcessState(i, null);
9019 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in);
9020 }
9021 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009022 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009023 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009024 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07009025
Dianne Hackborn617f8772009-03-31 15:04:46 -07009026 if (in.readInt() != 0) {
9027 if (u.mUserActivityCounters == null) {
9028 u.initUserActivityLocked();
9029 }
9030 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
9031 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
9032 }
9033 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009034
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009035 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009036 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009037 u.initNetworkActivityLocked();
9038 }
9039 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009040 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
9041 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009042 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009043 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
9044 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009045 }
9046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009047 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009048 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009049 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
9050 return;
9051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009052 for (int iw = 0; iw < NW; iw++) {
9053 String wlName = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07009054 u.readWakeSummaryFromParcelLocked(wlName, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009055 }
9056
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009057 int NS = in.readInt();
9058 if (NS > 100) {
9059 Slog.w(TAG, "File corrupt: too many syncs " + NS);
9060 return;
9061 }
9062 for (int is = 0; is < NS; is++) {
9063 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07009064 u.readSyncSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009065 }
9066
9067 int NJ = in.readInt();
9068 if (NJ > 100) {
9069 Slog.w(TAG, "File corrupt: too many job timers " + NJ);
9070 return;
9071 }
9072 for (int ij = 0; ij < NJ; ij++) {
9073 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07009074 u.readJobSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009075 }
9076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009077 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009078 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009079 Slog.w(TAG, "File corrupt: too many sensors " + NP);
9080 return;
9081 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009082 for (int is = 0; is < NP; is++) {
9083 int seNumber = in.readInt();
9084 if (in.readInt() != 0) {
9085 u.getSensorTimerLocked(seNumber, true)
9086 .readSummaryFromParcelLocked(in);
9087 }
9088 }
9089
9090 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009091 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009092 Slog.w(TAG, "File corrupt: too many processes " + NP);
9093 return;
9094 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009095 for (int ip = 0; ip < NP; ip++) {
9096 String procName = in.readString();
9097 Uid.Proc p = u.getProcessStatsLocked(procName);
9098 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009099 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009100 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009101 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009102 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt();
9103 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009104 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009105 if (NSB > 100) {
9106 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
9107 return;
9108 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009109 p.mSpeedBins = new SamplingCounter[NSB];
9110 for (int i=0; i<NSB; i++) {
9111 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009112 p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009113 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
9114 }
9115 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009116 if (!p.readExcessivePowerFromParcelLocked(in)) {
9117 return;
9118 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009119 }
9120
9121 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009122 if (NP > 10000) {
9123 Slog.w(TAG, "File corrupt: too many packages " + NP);
9124 return;
9125 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009126 for (int ip = 0; ip < NP; ip++) {
9127 String pkgName = in.readString();
9128 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009129 final int NWA = in.readInt();
9130 if (NWA > 1000) {
9131 Slog.w(TAG, "File corrupt: too many wakeup alarms " + NWA);
9132 return;
9133 }
9134 p.mWakeupAlarms.clear();
9135 for (int iwa=0; iwa<NWA; iwa++) {
9136 String tag = in.readString();
9137 Counter c = new Counter(mOnBatteryTimeBase);
9138 c.readSummaryFromParcelLocked(in);
9139 p.mWakeupAlarms.put(tag, c);
9140 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009141 NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009142 if (NS > 1000) {
9143 Slog.w(TAG, "File corrupt: too many services " + NS);
9144 return;
9145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009146 for (int is = 0; is < NS; is++) {
9147 String servName = in.readString();
9148 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
9149 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009150 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009151 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009152 }
9153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009154 }
9155 }
9156
9157 /**
9158 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
9159 * disk. This format does not allow a lossless round-trip.
9160 *
9161 * @param out the Parcel to be written to.
9162 */
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009163 public void writeSummaryToParcel(Parcel out, boolean inclHistory) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009164 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009165
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009166 // Pull the clock time. This may update the time and make a new history entry
9167 // if we had originally pulled a time before the RTC was set.
9168 long startClockTime = getStartClockTime();
9169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009170 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
9171 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009172
9173 out.writeInt(VERSION);
9174
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009175 writeHistory(out, inclHistory, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009177 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009178 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009179 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009180 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009181 out.writeString(mStartPlatformVersion);
9182 out.writeString(mEndPlatformVersion);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009183 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
9184 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009185 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009186 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07009187 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009188 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08009189 out.writeInt(getLowDischargeAmountSinceCharge());
9190 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009191 out.writeInt(getDischargeAmountScreenOnSinceCharge());
9192 out.writeInt(getDischargeAmountScreenOffSinceCharge());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009193 mDischargeStepTracker.writeToParcel(out);
9194 mChargeStepTracker.writeToParcel(out);
9195 mDailyDischargeStepTracker.writeToParcel(out);
9196 mDailyChargeStepTracker.writeToParcel(out);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009197 if (mDailyPackageChanges != null) {
9198 final int NPKG = mDailyPackageChanges.size();
9199 out.writeInt(NPKG);
9200 for (int i=0; i<NPKG; i++) {
9201 PackageChange pc = mDailyPackageChanges.get(i);
9202 out.writeString(pc.mPackageName);
9203 out.writeInt(pc.mUpdate ? 1 : 0);
9204 out.writeInt(pc.mVersionCode);
9205 }
9206 } else {
9207 out.writeInt(0);
9208 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009209 out.writeLong(mDailyStartTime);
9210 out.writeLong(mNextMinDailyDeadline);
9211 out.writeLong(mNextMaxDailyDeadline);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009212
9213 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009214 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009215 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009216 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009217 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009218 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9219 mDeviceIdleModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009220 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009221 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Wink Saville52840902011-02-18 12:40:47 -08009222 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009223 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009224 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009225 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009226 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009227 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009228 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009229 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009230 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
9231 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009232 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009233 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9234 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009235 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009236 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
9237 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009238 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9239 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009240 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009241 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009242 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009243 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9244 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9245 }
9246 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9247 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9248 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009249 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009250 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009251 mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009252 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009253 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9254 mBluetoothActivityCounters[i].writeSummaryFromParcelLocked(out);
9255 }
9256 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9257 mWifiActivityCounters[i].writeSummaryFromParcelLocked(out);
9258 }
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009259 out.writeInt(mNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009260 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009261
Evan Millarc64edde2009-04-18 12:26:32 -07009262 out.writeInt(mKernelWakelockStats.size());
9263 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
9264 Timer kwlt = ent.getValue();
9265 if (kwlt != null) {
9266 out.writeInt(1);
9267 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009268 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9269 } else {
9270 out.writeInt(0);
9271 }
9272 }
9273
9274 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009275 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
9276 SamplingTimer timer = ent.getValue();
9277 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009278 out.writeInt(1);
9279 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009280 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Evan Millarc64edde2009-04-18 12:26:32 -07009281 } else {
9282 out.writeInt(0);
9283 }
9284 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009285
Amith Yamasanie43530a2009-08-21 13:11:37 -07009286 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009287 final int NU = mUidStats.size();
9288 out.writeInt(NU);
9289 for (int iu = 0; iu < NU; iu++) {
9290 out.writeInt(mUidStats.keyAt(iu));
9291 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009292
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009293 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009294 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009295 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009296 } else {
9297 out.writeInt(0);
9298 }
9299 if (u.mFullWifiLockTimer != null) {
9300 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009301 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009302 } else {
9303 out.writeInt(0);
9304 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07009305 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009306 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009307 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009308 } else {
9309 out.writeInt(0);
9310 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07009311 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
9312 if (u.mWifiBatchedScanTimer[i] != null) {
9313 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009314 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Robert Greenwalta029ea12013-09-25 16:38:12 -07009315 } else {
9316 out.writeInt(0);
9317 }
9318 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009319 if (u.mWifiMulticastTimer != null) {
9320 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009321 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009322 } else {
9323 out.writeInt(0);
9324 }
9325 if (u.mAudioTurnedOnTimer != null) {
9326 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009327 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009328 } else {
9329 out.writeInt(0);
9330 }
9331 if (u.mVideoTurnedOnTimer != null) {
9332 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009333 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009334 } else {
9335 out.writeInt(0);
9336 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009337 if (u.mForegroundActivityTimer != null) {
9338 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009339 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009340 } else {
9341 out.writeInt(0);
9342 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07009343 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
9344 if (u.mProcessStateTimer[i] != null) {
9345 out.writeInt(1);
9346 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9347 } else {
9348 out.writeInt(0);
9349 }
9350 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009351 if (u.mVibratorOnTimer != null) {
9352 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009353 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009354 } else {
9355 out.writeInt(0);
9356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009357
Dianne Hackborn617f8772009-03-31 15:04:46 -07009358 if (u.mUserActivityCounters == null) {
9359 out.writeInt(0);
9360 } else {
9361 out.writeInt(1);
9362 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
9363 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
9364 }
9365 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009366
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009367 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009368 out.writeInt(0);
9369 } else {
9370 out.writeInt(1);
9371 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009372 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
9373 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009374 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009375 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
9376 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009377 }
9378
Dianne Hackbornd953c532014-08-16 18:17:38 -07009379 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
9380 int NW = wakeStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009381 out.writeInt(NW);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009382 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009383 out.writeString(wakeStats.keyAt(iw));
9384 Uid.Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009385 if (wl.mTimerFull != null) {
9386 out.writeInt(1);
9387 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9388 } else {
9389 out.writeInt(0);
9390 }
9391 if (wl.mTimerPartial != null) {
9392 out.writeInt(1);
9393 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9394 } else {
9395 out.writeInt(0);
9396 }
9397 if (wl.mTimerWindow != null) {
9398 out.writeInt(1);
9399 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9400 } else {
9401 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009402 }
9403 }
9404
Dianne Hackbornd953c532014-08-16 18:17:38 -07009405 final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap();
9406 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009407 out.writeInt(NS);
9408 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009409 out.writeString(syncStats.keyAt(is));
9410 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009411 }
9412
Dianne Hackbornd953c532014-08-16 18:17:38 -07009413 final ArrayMap<String, StopwatchTimer> jobStats = u.mJobStats.getMap();
9414 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009415 out.writeInt(NJ);
9416 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009417 out.writeString(jobStats.keyAt(ij));
9418 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009419 }
9420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009421 int NSE = u.mSensorStats.size();
9422 out.writeInt(NSE);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009423 for (int ise=0; ise<NSE; ise++) {
9424 out.writeInt(u.mSensorStats.keyAt(ise));
9425 Uid.Sensor se = u.mSensorStats.valueAt(ise);
9426 if (se.mTimer != null) {
9427 out.writeInt(1);
9428 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9429 } else {
9430 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009431 }
9432 }
9433
9434 int NP = u.mProcessStats.size();
9435 out.writeInt(NP);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009436 for (int ip=0; ip<NP; ip++) {
9437 out.writeString(u.mProcessStats.keyAt(ip));
9438 Uid.Proc ps = u.mProcessStats.valueAt(ip);
9439 out.writeLong(ps.mUserTime);
9440 out.writeLong(ps.mSystemTime);
9441 out.writeLong(ps.mForegroundTime);
9442 out.writeInt(ps.mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009443 out.writeInt(ps.mNumCrashes);
9444 out.writeInt(ps.mNumAnrs);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009445 final int N = ps.mSpeedBins.length;
9446 out.writeInt(N);
9447 for (int i=0; i<N; i++) {
9448 if (ps.mSpeedBins[i] != null) {
9449 out.writeInt(1);
9450 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
9451 } else {
9452 out.writeInt(0);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009454 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07009455 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009456 }
9457
9458 NP = u.mPackageStats.size();
9459 out.writeInt(NP);
9460 if (NP > 0) {
9461 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
9462 : u.mPackageStats.entrySet()) {
9463 out.writeString(ent.getKey());
9464 Uid.Pkg ps = ent.getValue();
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009465 final int NWA = ps.mWakeupAlarms.size();
9466 out.writeInt(NWA);
9467 for (int iwa=0; iwa<NWA; iwa++) {
9468 out.writeString(ps.mWakeupAlarms.keyAt(iwa));
9469 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out);
9470 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009471 NS = ps.mServiceStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009472 out.writeInt(NS);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009473 for (int is=0; is<NS; is++) {
9474 out.writeString(ps.mServiceStats.keyAt(is));
9475 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
9476 long time = ss.getStartTimeToNowLocked(
9477 mOnBatteryTimeBase.getUptime(NOW_SYS));
9478 out.writeLong(time);
9479 out.writeInt(ss.mStarts);
9480 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009481 }
9482 }
9483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009484 }
9485 }
9486
9487 public void readFromParcel(Parcel in) {
9488 readFromParcelLocked(in);
9489 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 void readFromParcelLocked(Parcel in) {
9492 int magic = in.readInt();
9493 if (magic != MAGIC) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009494 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009495 }
9496
Dianne Hackbornae384452011-06-28 12:33:48 -07009497 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009499 mStartCount = in.readInt();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009500 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009501 mStartPlatformVersion = in.readString();
9502 mEndPlatformVersion = in.readString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009503 mUptime = in.readLong();
9504 mUptimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009505 mRealtime = in.readLong();
9506 mRealtimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009507 mOnBattery = in.readInt() != 0;
9508 mOnBatteryInternal = false; // we are no longer really running.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009509 mOnBatteryTimeBase.readFromParcel(in);
9510 mOnBatteryScreenOffTimeBase.readFromParcel(in);
9511
Jeff Browne95c3cd2014-05-02 16:59:26 -07009512 mScreenState = Display.STATE_UNKNOWN;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009513 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase, in);
9514 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
9515 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase,
9516 in);
9517 }
Dianne Hackborn29325132014-05-21 15:01:03 -07009518 mInteractive = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009519 mInteractiveTimer = new StopwatchTimer(null, -10, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009520 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009521 mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
9522 mDeviceIdleModeEnabledTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase, in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009523 mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase, in);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009524 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009525 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
9526 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
9527 null, mOnBatteryTimeBase, in);
9528 }
9529 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase, in);
9530 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
9531 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
9532 null, mOnBatteryTimeBase, in);
9533 }
9534 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
9535 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9536 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9537 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009538 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009539 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in);
9540 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase,
9541 in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009542 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009543 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
9544 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
9545 mWifiOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009546 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009547 mGlobalWifiRunning = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009548 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009549 for (int i=0; i<NUM_WIFI_STATES; i++) {
9550 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
9551 null, mOnBatteryTimeBase, in);
9552 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009553 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9554 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i,
9555 null, mOnBatteryTimeBase, in);
9556 }
9557 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9558 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i,
9559 null, mOnBatteryTimeBase, in);
9560 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009561 mBluetoothOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009562 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009563 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
9564 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i,
9565 null, mOnBatteryTimeBase, in);
9566 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009567
9568 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9569 mBluetoothActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9570 }
9571
9572 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9573 mWifiActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9574 }
9575
Adam Lesinski17390762015-04-10 13:17:47 -07009576 mHasWifiEnergyReporting = in.readInt() != 0;
9577 mHasBluetoothEnergyReporting = in.readInt() != 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009578 mNumConnectivityChange = in.readInt();
9579 mLoadedNumConnectivityChange = in.readInt();
9580 mUnpluggedNumConnectivityChange = in.readInt();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07009581 mAudioOnNesting = 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009582 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
Dianne Hackborn10eaa852014-07-22 22:54:55 -07009583 mVideoOnNesting = 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009584 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009585 mFlashlightOn = false;
9586 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009587 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009588 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07009589 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009590 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009591 mLowDischargeAmountSinceCharge = in.readInt();
9592 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009593 mDischargeAmountScreenOn = in.readInt();
9594 mDischargeAmountScreenOnSinceCharge = in.readInt();
9595 mDischargeAmountScreenOff = in.readInt();
9596 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009597 mDischargeStepTracker.readFromParcel(in);
9598 mChargeStepTracker.readFromParcel(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009599 mLastWriteTime = in.readLong();
9600
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07009601 mBluetoothPingCount = in.readInt();
9602 mBluetoothPingStart = -1;
9603
Evan Millarc64edde2009-04-18 12:26:32 -07009604 mKernelWakelockStats.clear();
9605 int NKW = in.readInt();
9606 for (int ikw = 0; ikw < NKW; ikw++) {
9607 if (in.readInt() != 0) {
9608 String wakelockName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009609 SamplingTimer kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07009610 mKernelWakelockStats.put(wakelockName, kwlt);
9611 }
9612 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009613
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009614 mWakeupReasonStats.clear();
9615 int NWR = in.readInt();
9616 for (int iwr = 0; iwr < NWR; iwr++) {
9617 if (in.readInt() != 0) {
9618 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009619 SamplingTimer timer = new SamplingTimer(mOnBatteryTimeBase, in);
9620 mWakeupReasonStats.put(reasonName, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009621 }
9622 }
9623
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009624 mPartialTimers.clear();
9625 mFullTimers.clear();
9626 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009627 mWifiRunningTimers.clear();
9628 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -07009629 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -07009630 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009631 mWifiMulticastTimers.clear();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07009632 mAudioTurnedOnTimers.clear();
9633 mVideoTurnedOnTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634
Amith Yamasanie43530a2009-08-21 13:11:37 -07009635 sNumSpeedSteps = in.readInt();
9636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009637 int numUids = in.readInt();
9638 mUidStats.clear();
9639 for (int i = 0; i < numUids; i++) {
9640 int uid = in.readInt();
9641 Uid u = new Uid(uid);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009642 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009643 mUidStats.append(uid, u);
9644 }
9645 }
9646
9647 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009648 writeToParcelLocked(out, true, flags);
9649 }
9650
9651 public void writeToParcelWithoutUids(Parcel out, int flags) {
9652 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009653 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009654
9655 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009656 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009657 // Need to update with current kernel wake lock counts.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009658 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009659
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009660 // Pull the clock time. This may update the time and make a new history entry
9661 // if we had originally pulled a time before the RTC was set.
9662 long startClockTime = getStartClockTime();
9663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009664 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
9665 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009666 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
9667 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009669 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009670
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009671 writeHistory(out, true, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009673 out.writeInt(mStartCount);
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009674 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009675 out.writeString(mStartPlatformVersion);
9676 out.writeString(mEndPlatformVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009677 out.writeLong(mUptime);
9678 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009679 out.writeLong(mRealtime);
9680 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009681 out.writeInt(mOnBattery ? 1 : 0);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009682 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
9683 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
9684
9685 mScreenOnTimer.writeToParcel(out, uSecRealtime);
9686 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
9687 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
9688 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009689 mInteractiveTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009690 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime);
9691 mDeviceIdleModeEnabledTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009692 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009693 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
9694 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
9695 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
9696 }
9697 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
9698 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
9699 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
9700 }
9701 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
9702 mNetworkByteActivityCounters[i].writeToParcel(out);
9703 mNetworkPacketActivityCounters[i].writeToParcel(out);
9704 }
9705 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
9706 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009707 mMobileRadioActiveAdjustedTime.writeToParcel(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009708 mMobileRadioActiveUnknownTime.writeToParcel(out);
9709 mMobileRadioActiveUnknownCount.writeToParcel(out);
9710 mWifiOnTimer.writeToParcel(out, uSecRealtime);
9711 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
9712 for (int i=0; i<NUM_WIFI_STATES; i++) {
9713 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
9714 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009715 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9716 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime);
9717 }
9718 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9719 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
9720 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009721 mBluetoothOnTimer.writeToParcel(out, uSecRealtime);
9722 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
9723 mBluetoothStateTimer[i].writeToParcel(out, uSecRealtime);
9724 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009725 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9726 mBluetoothActivityCounters[i].writeToParcel(out);
9727 }
9728 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9729 mWifiActivityCounters[i].writeToParcel(out);
9730 }
Adam Lesinski17390762015-04-10 13:17:47 -07009731 out.writeInt(mHasWifiEnergyReporting ? 1 : 0);
9732 out.writeInt(mHasBluetoothEnergyReporting ? 1 : 0);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009733 out.writeInt(mNumConnectivityChange);
9734 out.writeInt(mLoadedNumConnectivityChange);
9735 out.writeInt(mUnpluggedNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009736 mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009737 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009738 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07009739 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009740 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009741 out.writeInt(mLowDischargeAmountSinceCharge);
9742 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009743 out.writeInt(mDischargeAmountScreenOn);
9744 out.writeInt(mDischargeAmountScreenOnSinceCharge);
9745 out.writeInt(mDischargeAmountScreenOff);
9746 out.writeInt(mDischargeAmountScreenOffSinceCharge);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009747 mDischargeStepTracker.writeToParcel(out);
9748 mChargeStepTracker.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009749 out.writeLong(mLastWriteTime);
9750
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07009751 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07009752
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009753 if (inclUids) {
9754 out.writeInt(mKernelWakelockStats.size());
9755 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
9756 SamplingTimer kwlt = ent.getValue();
9757 if (kwlt != null) {
9758 out.writeInt(1);
9759 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009760 kwlt.writeToParcel(out, uSecRealtime);
9761 } else {
9762 out.writeInt(0);
9763 }
9764 }
9765 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009766 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
9767 SamplingTimer timer = ent.getValue();
9768 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009769 out.writeInt(1);
9770 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009771 timer.writeToParcel(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009772 } else {
9773 out.writeInt(0);
9774 }
Evan Millarc64edde2009-04-18 12:26:32 -07009775 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009776 } else {
9777 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07009778 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07009779
9780 out.writeInt(sNumSpeedSteps);
9781
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009782 if (inclUids) {
9783 int size = mUidStats.size();
9784 out.writeInt(size);
9785 for (int i = 0; i < size; i++) {
9786 out.writeInt(mUidStats.keyAt(i));
9787 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009788
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009789 uid.writeToParcelLocked(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009790 }
9791 } else {
9792 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009793 }
9794 }
9795
9796 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
9797 new Parcelable.Creator<BatteryStatsImpl>() {
9798 public BatteryStatsImpl createFromParcel(Parcel in) {
9799 return new BatteryStatsImpl(in);
9800 }
9801
9802 public BatteryStatsImpl[] newArray(int size) {
9803 return new BatteryStatsImpl[size];
9804 }
9805 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009806
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009807 public void prepareForDumpLocked() {
9808 // Need to retrieve current kernel wake lock stats before printing.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009809 pullPendingStateUpdatesLocked();
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009810
9811 // Pull the clock time. This may update the time and make a new history entry
9812 // if we had originally pulled a time before the RTC was set.
9813 getStartClockTime();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009814 }
9815
Dianne Hackbornc51cf032014-03-02 19:08:15 -08009816 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009817 if (DEBUG) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009818 pw.println("mOnBatteryTimeBase:");
9819 mOnBatteryTimeBase.dump(pw, " ");
9820 pw.println("mOnBatteryScreenOffTimeBase:");
9821 mOnBatteryScreenOffTimeBase.dump(pw, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009822 Printer pr = new PrintWriterPrinter(pw);
9823 pr.println("*** Screen timer:");
9824 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07009825 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009826 pr.println("*** Screen brightness #" + i + ":");
9827 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07009828 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009829 pr.println("*** Interactive timer:");
9830 mInteractiveTimer.logState(pr, " ");
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009831 pr.println("*** Power save mode timer:");
9832 mPowerSaveModeEnabledTimer.logState(pr, " ");
9833 pr.println("*** Device idle mode timer:");
9834 mDeviceIdleModeEnabledTimer.logState(pr, " ");
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009835 pr.println("*** Device idling timer:");
9836 mDeviceIdlingTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009837 pr.println("*** Phone timer:");
9838 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08009839 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3251b902014-06-20 14:40:53 -07009840 pr.println("*** Phone signal strength #" + i + ":");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009841 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07009842 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07009843 pr.println("*** Signal scanning :");
9844 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07009845 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009846 pr.println("*** Data connection type #" + i + ":");
9847 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07009848 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009849 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009850 pr.println("*** Mobile network active timer:");
9851 mMobileRadioActiveTimer.logState(pr, " ");
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009852 pr.println("*** Mobile network active adjusted timer:");
9853 mMobileRadioActiveAdjustedTime.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009854 pr.println("*** Wifi timer:");
9855 mWifiOnTimer.logState(pr, " ");
9856 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009857 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009858 for (int i=0; i<NUM_WIFI_STATES; i++) {
9859 pr.println("*** Wifi state #" + i + ":");
9860 mWifiStateTimer[i].logState(pr, " ");
9861 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009862 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9863 pr.println("*** Wifi suppl state #" + i + ":");
9864 mWifiSupplStateTimer[i].logState(pr, " ");
9865 }
9866 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9867 pr.println("*** Wifi signal strength #" + i + ":");
9868 mWifiSignalStrengthsTimer[i].logState(pr, " ");
9869 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009870 pr.println("*** Bluetooth timer:");
9871 mBluetoothOnTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009872 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009873 pr.println("*** Bluetooth active type #" + i + ":");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009874 mBluetoothStateTimer[i].logState(pr, " ");
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009875 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009876 pr.println("*** Flashlight timer:");
9877 mFlashlightOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009878 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08009879 super.dumpLocked(context, pw, flags, reqUid, histStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009881}