blob: 082f1a5837639f59ef0ef4b18d2f7c8f20921df5 [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
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080019import static android.net.NetworkStats.UID_ALL;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080020import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070021
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;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070025import android.net.ConnectivityManager;
26import android.net.NetworkStats;
Dianne Hackborn00e25212014-02-19 10:49:24 -080027import android.os.BadParcelableException;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070028import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.os.BatteryStats;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070030import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070031import android.os.Handler;
Jeff Brown6f357d32014-01-15 20:40:55 -080032import android.os.Looper;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070033import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.os.Parcel;
35import android.os.ParcelFormatException;
36import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070037import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.os.SystemClock;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080039import android.os.SystemProperties;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070040import android.os.WorkSource;
Amith Yamasanif37447b2009-10-08 18:28:01 -070041import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070042import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070043import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070045import android.util.LogWriter;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070046import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070048import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.util.SparseArray;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080050import android.util.SparseBooleanArray;
Dianne Hackborn099bc622014-01-22 13:39:16 -080051import android.util.SparseIntArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070052import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070054import com.android.internal.annotations.GuardedBy;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070055import com.android.internal.net.NetworkStatsFactory;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080056import com.android.internal.util.ArrayUtils;
Dianne Hackborn8c841092013-06-24 13:46:13 -070057import com.android.internal.util.FastPrintWriter;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070058import com.android.internal.util.JournaledFile;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import java.io.File;
61import java.io.FileInputStream;
62import java.io.FileOutputStream;
63import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070064import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import java.util.ArrayList;
66import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070067import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070068import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070070import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070071import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
73/**
74 * All information we are collecting about things that can happen that impact
75 * battery life. All times are represented in microseconds except where indicated
76 * otherwise.
77 */
78public final class BatteryStatsImpl extends BatteryStats {
79 private static final String TAG = "BatteryStatsImpl";
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080080 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070081 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -070082 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070083
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070084 // TODO: remove "tcp" from network methods, since we measure total stats.
85
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070087 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
89 // Current on-disk Parcel version
Dianne Hackborne5167ca2014-03-08 14:39:10 -080090 private static final int VERSION = 99 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -070091
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070092 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070093 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070094
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070095 // No, really, THIS is the maximum number of items we will record in the history.
96 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
97
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080098 // The maximum number of names wakelocks we will keep track of
99 // per uid; once the limit is reached, we batch the remaining wakelocks
100 // in to one common name.
Dianne Hackbornaf17baa2013-05-09 15:27:47 -0700101 private static final int MAX_WAKELOCKS_PER_UID = 50;
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700102
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800103 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700104
Amith Yamasanie43530a2009-08-21 13:11:37 -0700105 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700107 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700109 static final int MSG_UPDATE_WAKELOCKS = 1;
110 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700111 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700112
113 public interface BatteryCallback {
114 public void batteryNeedsCpuUpdate();
115 public void batteryPowerChanged(boolean onBattery);
116 }
117
118 final class MyHandler extends Handler {
Jeff Brown6f357d32014-01-15 20:40:55 -0800119 public MyHandler(Looper looper) {
120 super(looper, null, true);
121 }
122
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700123 @Override
124 public void handleMessage(Message msg) {
125 BatteryCallback cb = mCallback;
126 switch (msg.what) {
127 case MSG_UPDATE_WAKELOCKS:
128 if (cb != null) {
129 cb.batteryNeedsCpuUpdate();
130 }
131 break;
132 case MSG_REPORT_POWER_CHANGE:
133 if (cb != null) {
134 cb.batteryPowerChanged(msg.arg1 != 0);
135 }
136 break;
137 }
138 }
139 }
140
141 private final MyHandler mHandler;
142
143 private BatteryCallback mCallback;
144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -0800146 * Mapping isolated uids to the actual owning app uid.
147 */
148 final SparseIntArray mIsolatedUids = new SparseIntArray();
149
150 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 * The statistics we have collected organized by uids.
152 */
153 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
154 new SparseArray<BatteryStatsImpl.Uid>();
155
156 // A set of pools of currently active timers. When a timer is queried, we will divide the
157 // elapsed time by the number of active timers to arrive at that timer's share of the time.
158 // In order to do this, we must refresh each timer whenever the number of active timers
159 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700160 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
161 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
162 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
163 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
164 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700165 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
166 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700167 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
Nick Pelly6ccaa542012-06-15 15:22:47 -0700168 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>();
Robert Greenwalta029ea12013-09-25 16:38:12 -0700169 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers =
170 new SparseArray<ArrayList<StopwatchTimer>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700172 // Last partial timers we use for distributing CPU usage.
173 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 // These are the objects that will want to do something when the device
176 // is unplugged from power.
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800177 final TimeBase mOnBatteryTimeBase = new TimeBase();
178
179 // These are the objects that will want to do something when the device
180 // is unplugged from power *and* the screen is off.
181 final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
182
183 // Set to true when we want to distribute CPU across wakelocks for the next
184 // CPU update, even if we aren't currently running wake locks.
185 boolean mDistributeWakelockCpu;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700186
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700187 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700188
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800189 HashMap<String, SparseBooleanArray>[] mActiveEvents
190 = (HashMap<String, SparseBooleanArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
191
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700192 long mHistoryBaseTime;
193 boolean mHaveBatteryLevel = false;
194 boolean mRecordingHistory = true;
195 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700196
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700197 static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
198 static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700199 final Parcel mHistoryBuffer = Parcel.obtain();
200 final HistoryItem mHistoryLastWritten = new HistoryItem();
201 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700202 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800203 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<HistoryTag, Integer>();
Dianne Hackborn099bc622014-01-22 13:39:16 -0800204 String[] mReadHistoryStrings;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800205 int[] mReadHistoryUids;
206 int mReadHistoryChars;
207 int mNextHistoryTagIdx = 0;
208 int mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700209 int mHistoryBufferLastPos = -1;
210 boolean mHistoryOverflow = false;
Dianne Hackborn40c87252014-03-19 16:55:40 -0700211 long mLastHistoryElapsedRealtime = 0;
212 long mLastHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700213
214 final HistoryItem mHistoryCur = new HistoryItem();
215
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700216 HistoryItem mHistory;
217 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700218 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700219 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700220
221 private HistoryItem mHistoryIterator;
222 private boolean mReadOverflow;
223 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 int mStartCount;
226
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800227 long mStartClockTime;
228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 long mUptime;
230 long mUptimeStart;
231 long mLastUptime;
232 long mRealtime;
233 long mRealtimeStart;
234 long mLastRealtime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700235
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800236 int mWakeLockNesting;
237 boolean mWakeLockImportant;
238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700240 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700241
Dianne Hackborn617f8772009-03-31 15:04:46 -0700242 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700243 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700244
Dianne Hackborn617f8772009-03-31 15:04:46 -0700245 Counter mInputEventCounter;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700248 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700249
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700250 boolean mAudioOn;
251 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700252
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700253 boolean mVideoOn;
254 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700255
Dianne Hackborn627bba72009-03-24 22:32:56 -0700256 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800257 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700258 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800259 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700260
261 StopwatchTimer mPhoneSignalScanningTimer;
262
Dianne Hackborn627bba72009-03-24 22:32:56 -0700263 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700264 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700265 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700266
Dianne Hackborn57ed6a62013-12-09 18:15:56 -0800267 final LongSamplingCounter[] mNetworkByteActivityCounters =
268 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
269 final LongSamplingCounter[] mNetworkPacketActivityCounters =
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700270 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
271
The Android Open Source Project10592532009-03-18 17:39:46 -0700272 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700273 StopwatchTimer mWifiOnTimer;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700274
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700275 boolean mGlobalWifiRunning;
276 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700277
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800278 int mWifiState = -1;
279 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
280
The Android Open Source Project10592532009-03-18 17:39:46 -0700281 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700282 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700283
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800284 int mBluetoothState = -1;
285 final StopwatchTimer[] mBluetoothStateTimer = new StopwatchTimer[NUM_BLUETOOTH_STATES];
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800286
287 boolean mMobileRadioActive;
288 StopwatchTimer mMobileRadioActiveTimer;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800289 StopwatchTimer mMobileRadioActivePerAppTimer;
Dianne Hackbornd45665b2014-02-26 12:35:32 -0800290 LongSamplingCounter mMobileRadioActiveUnknownTime;
291 LongSamplingCounter mMobileRadioActiveUnknownCount;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800292
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700293 /** Bluetooth headset object */
294 BluetoothHeadset mBtHeadset;
295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 /**
297 * These provide time bases that discount the time the device is plugged
298 * in to power.
299 */
300 boolean mOnBattery;
301 boolean mOnBatteryInternal;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700302
The Android Open Source Project10592532009-03-18 17:39:46 -0700303 /*
304 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
305 */
Evan Millar633a1742009-04-02 16:36:33 -0700306 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700307 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700308 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700309 int mLowDischargeAmountSinceCharge;
310 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800311 int mDischargeScreenOnUnplugLevel;
312 int mDischargeScreenOffUnplugLevel;
313 int mDischargeAmountScreenOn;
314 int mDischargeAmountScreenOnSinceCharge;
315 int mDischargeAmountScreenOff;
316 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700319
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700320 private int mBluetoothPingCount;
321 private int mBluetoothPingStart = -1;
322
Amith Yamasanif37447b2009-10-08 18:28:01 -0700323 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800324 private int mPhoneServiceStateRaw = -1;
325 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700326
Evan Millarc64edde2009-04-18 12:26:32 -0700327 /*
328 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
329 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700330 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700331 new HashMap<String, SamplingTimer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700332
Evan Millarc64edde2009-04-18 12:26:32 -0700333 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
334 return mKernelWakelockStats;
335 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700336
Evan Millarc64edde2009-04-18 12:26:32 -0700337 private static int sKernelWakelockUpdateVersion = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700338
Evan Millarc64edde2009-04-18 12:26:32 -0700339 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
Dianne Hackborn13ac0412013-06-25 19:34:49 -0700340 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name
341 Process.PROC_QUOTES,
Evan Millarc64edde2009-04-18 12:26:32 -0700342 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
343 Process.PROC_TAB_TERM,
344 Process.PROC_TAB_TERM,
345 Process.PROC_TAB_TERM,
346 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
347 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700348
Todd Poynor73f534a2012-06-19 11:07:26 -0700349 private static final int[] WAKEUP_SOURCES_FORMAT = new int[] {
350 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
351 Process.PROC_TAB_TERM|Process.PROC_COMBINE|
352 Process.PROC_OUT_LONG, // 1: count
353 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
354 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
355 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
356 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
357 Process.PROC_TAB_TERM|Process.PROC_COMBINE
358 |Process.PROC_OUT_LONG, // 6: totalTime
359 };
360
Evan Millarc64edde2009-04-18 12:26:32 -0700361 private final String[] mProcWakelocksName = new String[3];
362 private final long[] mProcWakelocksData = new long[3];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700363
Evan Millarc64edde2009-04-18 12:26:32 -0700364 /*
365 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
366 * to mKernelWakelockStats.
367 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700368 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700369 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700371 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -0800372 private NetworkStats mCurMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
373 private NetworkStats mLastMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
374 private NetworkStats mCurWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
375 private NetworkStats mLastWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -0800376 private NetworkStats mTmpNetworkStats;
377 private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700378
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700379 @GuardedBy("this")
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -0800380 private String[] mMobileIfaces = new String[0];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700381 @GuardedBy("this")
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -0800382 private String[] mWifiIfaces = new String[0];
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 // For debugging
385 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700386 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700387 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 }
389
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800390 public static interface TimeBaseObs {
391 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
392 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
393 }
394
395 static class TimeBase {
396 private final ArrayList<TimeBaseObs> mObservers = new ArrayList<TimeBaseObs>();
397
398 private long mUptime;
399 private long mLastUptime;
400 private long mRealtime;
401 private long mLastRealtime;
402
403 private boolean mRunning;
404
405 private long mPastUptime;
406 private long mUptimeStart;
407 private long mPastRealtime;
408 private long mRealtimeStart;
409 private long mUnpluggedUptime;
410 private long mUnpluggedRealtime;
411
412 public void dump(PrintWriter pw, String prefix) {
413 StringBuilder sb = new StringBuilder(128);
414 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
415 sb.setLength(0);
416 sb.append(prefix);
417 sb.append("mUptime=");
418 formatTimeMs(sb, mUptime / 1000); sb.append("mLastUptime=");
419 formatTimeMs(sb, mLastUptime / 1000);
420 pw.println(sb.toString());
421 sb.setLength(0);
422 sb.append(prefix);
423 sb.append("mRealtime=");
424 formatTimeMs(sb, mRealtime / 1000); sb.append("mLastRealtime=");
425 formatTimeMs(sb, mLastRealtime / 1000);
426 pw.println(sb.toString());
427 sb.setLength(0);
428 sb.append(prefix);
429 sb.append("mPastUptime=");
430 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
431 formatTimeMs(sb, mUptimeStart / 1000);
432 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
433 pw.println(sb.toString());
434 sb.setLength(0);
435 sb.append(prefix);
436 sb.append("mPastRealtime=");
437 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
438 formatTimeMs(sb, mRealtimeStart / 1000);
439 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
440 pw.println(sb.toString());
441 }
442
443 public void add(TimeBaseObs observer) {
444 mObservers.add(observer);
445 }
446
447 public void remove(TimeBaseObs observer) {
448 if (!mObservers.remove(observer)) {
449 Slog.wtf(TAG, "Removed unknown observer: " + observer);
450 }
451 }
452
453 public void init(long uptime, long realtime) {
454 mRealtime = 0;
455 mUptime = 0;
456 mPastUptime = 0;
457 mPastRealtime = 0;
458 mUptimeStart = uptime;
459 mRealtimeStart = realtime;
460 mUnpluggedUptime = getUptime(mUptimeStart);
461 mUnpluggedRealtime = getRealtime(mRealtimeStart);
462 }
463
464 public void reset(long uptime, long realtime) {
465 if (!mRunning) {
466 mPastUptime = 0;
467 mPastRealtime = 0;
468 } else {
469 mUptimeStart = uptime;
470 mRealtimeStart = realtime;
471 mUnpluggedUptime = getUptime(uptime);
472 mUnpluggedRealtime = getRealtime(realtime);
473 }
474 }
475
476 public long computeUptime(long curTime, int which) {
477 switch (which) {
478 case STATS_SINCE_CHARGED:
479 return mUptime + getUptime(curTime);
480 case STATS_LAST:
481 return mLastUptime;
482 case STATS_CURRENT:
483 return getUptime(curTime);
484 case STATS_SINCE_UNPLUGGED:
485 return getUptime(curTime) - mUnpluggedUptime;
486 }
487 return 0;
488 }
489
490 public long computeRealtime(long curTime, int which) {
491 switch (which) {
492 case STATS_SINCE_CHARGED:
493 return mRealtime + getRealtime(curTime);
494 case STATS_LAST:
495 return mLastRealtime;
496 case STATS_CURRENT:
497 return getRealtime(curTime);
498 case STATS_SINCE_UNPLUGGED:
499 return getRealtime(curTime) - mUnpluggedRealtime;
500 }
501 return 0;
502 }
503
504 public long getUptime(long curTime) {
505 long time = mPastUptime;
506 if (mRunning) {
507 time += curTime - mUptimeStart;
508 }
509 return time;
510 }
511
512 public long getRealtime(long curTime) {
513 long time = mPastRealtime;
514 if (mRunning) {
515 time += curTime - mRealtimeStart;
516 }
517 return time;
518 }
519
520 public long getUptimeStart() {
521 return mUptimeStart;
522 }
523
524 public long getRealtimeStart() {
525 return mRealtimeStart;
526 }
527
528 public boolean isRunning() {
529 return mRunning;
530 }
531
532 public boolean setRunning(boolean running, long uptime, long realtime) {
533 if (mRunning != running) {
534 mRunning = running;
535 if (running) {
536 mUptimeStart = uptime;
537 mRealtimeStart = realtime;
538 long batteryUptime = mUnpluggedUptime = getUptime(uptime);
539 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
540
541 for (int i = mObservers.size() - 1; i >= 0; i--) {
542 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
543 }
544 } else {
545 mPastUptime += uptime - mUptimeStart;
546 mPastRealtime += realtime - mRealtimeStart;
547
548 long batteryUptime = getUptime(uptime);
549 long batteryRealtime = getRealtime(realtime);
550
551 for (int i = mObservers.size() - 1; i >= 0; i--) {
552 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
553 }
554 }
555 return true;
556 }
557 return false;
558 }
559
560 public void readSummaryFromParcel(Parcel in) {
561 mUptime = in.readLong();
562 mRealtime = in.readLong();
563 }
564
565 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
566 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
567 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
568 }
569
570 public void readFromParcel(Parcel in) {
571 mRunning = false;
572 mUptime = in.readLong();
573 mLastUptime = 0;
574 mPastUptime = in.readLong();
575 mUptimeStart = in.readLong();
576 mPastRealtime = in.readLong();
577 mRealtimeStart = in.readLong();
578 mUnpluggedUptime = in.readLong();
579 mUnpluggedRealtime = in.readLong();
580 }
581
582 public void writeToParcel(Parcel out, long uptime, long realtime) {
583 final long runningUptime = getUptime(uptime);
584 final long runningRealtime = getRealtime(realtime);
585 out.writeLong(mUptime);
586 out.writeLong(runningUptime);
587 out.writeLong(mUptimeStart);
588 out.writeLong(runningRealtime);
589 out.writeLong(mRealtimeStart);
590 out.writeLong(mUnpluggedUptime);
591 out.writeLong(mUnpluggedRealtime);
592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700596 * State for keeping track of counting information.
597 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800598 public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
Christopher Tate4cee7252010-03-19 14:50:40 -0700599 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800600 final TimeBase mTimeBase;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700601 int mLoadedCount;
602 int mLastCount;
603 int mUnpluggedCount;
604 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700605
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800606 Counter(TimeBase timeBase, Parcel in) {
607 mTimeBase = timeBase;
Christopher Tate4cee7252010-03-19 14:50:40 -0700608 mPluggedCount = in.readInt();
609 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700610 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700611 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700612 mUnpluggedCount = in.readInt();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800613 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700614 }
615
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800616 Counter(TimeBase timeBase) {
617 mTimeBase = timeBase;
618 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700619 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700620
Dianne Hackborn617f8772009-03-31 15:04:46 -0700621 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700622 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700623 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700624 out.writeInt(mUnpluggedCount);
625 }
626
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800627 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700628 mUnpluggedCount = mPluggedCount;
629 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700630 }
631
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800632 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700633 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700634 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700635
Dianne Hackborn617f8772009-03-31 15:04:46 -0700636 /**
637 * Writes a possibly null Counter to a Parcel.
638 *
639 * @param out the Parcel to be written to.
640 * @param counter a Counter, or null.
641 */
642 public static void writeCounterToParcel(Parcel out, Counter counter) {
643 if (counter == null) {
644 out.writeInt(0); // indicates null
645 return;
646 }
647 out.writeInt(1); // indicates non-null
648
649 counter.writeToParcel(out);
650 }
651
652 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700653 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700654 int val;
655 if (which == STATS_LAST) {
656 val = mLastCount;
657 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700658 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700659 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700660 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700661 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700662 val -= mLoadedCount;
663 }
664 }
665
666 return val;
667 }
668
669 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700670 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700671 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
672 + " mUnpluggedCount=" + mUnpluggedCount
673 + " mPluggedCount=" + mPluggedCount);
674 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700675
Christopher Tate4cee7252010-03-19 14:50:40 -0700676 void stepAtomic() {
677 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700678 }
679
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700680 /**
681 * Clear state of this counter.
682 */
683 void reset(boolean detachIfReset) {
684 mCount.set(0);
685 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
686 if (detachIfReset) {
687 detach();
688 }
689 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700690
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700691 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800692 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700693 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700694
Dianne Hackborn617f8772009-03-31 15:04:46 -0700695 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700696 int count = mCount.get();
697 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700698 }
699
700 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700701 mLoadedCount = in.readInt();
702 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700703 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700704 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700705 }
706 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700707
708 public static class SamplingCounter extends Counter {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800709 SamplingCounter(TimeBase timeBase, Parcel in) {
710 super(timeBase, in);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700711 }
712
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800713 SamplingCounter(TimeBase timeBase) {
714 super(timeBase);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700715 }
716
Christopher Tate4cee7252010-03-19 14:50:40 -0700717 public void addCountAtomic(long count) {
718 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700719 }
720 }
721
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800722 public static class LongSamplingCounter implements TimeBaseObs {
723 final TimeBase mTimeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700724 long mCount;
725 long mLoadedCount;
726 long mLastCount;
727 long mUnpluggedCount;
728 long mPluggedCount;
729
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800730 LongSamplingCounter(TimeBase timeBase, Parcel in) {
731 mTimeBase = timeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700732 mPluggedCount = in.readLong();
733 mCount = mPluggedCount;
734 mLoadedCount = in.readLong();
735 mLastCount = 0;
736 mUnpluggedCount = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800737 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700738 }
739
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800740 LongSamplingCounter(TimeBase timeBase) {
741 mTimeBase = timeBase;
742 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700743 }
744
745 public void writeToParcel(Parcel out) {
746 out.writeLong(mCount);
747 out.writeLong(mLoadedCount);
748 out.writeLong(mUnpluggedCount);
749 }
750
751 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800752 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700753 mUnpluggedCount = mPluggedCount;
754 mCount = mPluggedCount;
755 }
756
757 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800758 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700759 mPluggedCount = mCount;
760 }
761
762 public long getCountLocked(int which) {
763 long val;
764 if (which == STATS_LAST) {
765 val = mLastCount;
766 } else {
767 val = mCount;
768 if (which == STATS_SINCE_UNPLUGGED) {
769 val -= mUnpluggedCount;
770 } else if (which != STATS_SINCE_CHARGED) {
771 val -= mLoadedCount;
772 }
773 }
774
775 return val;
776 }
777
778 void addCountLocked(long count) {
779 mCount += count;
780 }
781
782 /**
783 * Clear state of this counter.
784 */
785 void reset(boolean detachIfReset) {
786 mCount = 0;
787 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
788 if (detachIfReset) {
789 detach();
790 }
791 }
792
793 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800794 mTimeBase.remove(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700795 }
796
797 void writeSummaryFromParcelLocked(Parcel out) {
798 out.writeLong(mCount);
799 }
800
801 void readSummaryFromParcelLocked(Parcel in) {
802 mLoadedCount = in.readLong();
803 mCount = mLoadedCount;
804 mLastCount = 0;
805 mUnpluggedCount = mPluggedCount = mLoadedCount;
806 }
807 }
808
Dianne Hackborn617f8772009-03-31 15:04:46 -0700809 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 * State for keeping track of timing information.
811 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800812 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 final int mType;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800814 final TimeBase mTimeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 int mCount;
817 int mLoadedCount;
818 int mLastCount;
819 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 // Times are in microseconds for better accuracy when dividing by the
822 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 /**
825 * The total time we have accumulated since the start of the original
826 * boot, to the last time something interesting happened in the
827 * current run.
828 */
829 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800831 /**
832 * The total time we loaded for the previous runs. Subtract this from
833 * mTotalTime to find the time for the current run of the system.
834 */
835 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700836
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 /**
838 * The run time of the last run of the system, as loaded from the
839 * saved data.
840 */
841 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 /**
844 * The value of mTotalTime when unplug() was last called. Subtract
845 * this from mTotalTime to find the time since the last unplug from
846 * power.
847 */
848 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700849
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700850 /**
851 * Constructs from a parcel.
852 * @param type
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800853 * @param timeBase
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700854 * @param in
855 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800856 Timer(int type, TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800858 mTimeBase = timeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 mCount = in.readInt();
861 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700862 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 mUnpluggedCount = in.readInt();
864 mTotalTime = in.readLong();
865 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700866 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 mUnpluggedTime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800868 timeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 }
870
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800871 Timer(int type, TimeBase timeBase) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800873 mTimeBase = timeBase;
874 timeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 }
Evan Millarc64edde2009-04-18 12:26:32 -0700876
877 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700878
Evan Millarc64edde2009-04-18 12:26:32 -0700879 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700880
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700881 /**
882 * Clear state of this timer. Returns true if the timer is inactive
883 * so can be completely dropped.
884 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800885 boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700886 mTotalTime = mLoadedTime = mLastTime = 0;
887 mCount = mLoadedCount = mLastCount = 0;
888 if (detachIfReset) {
889 detach();
890 }
891 return true;
892 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700893
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700894 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800895 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700896 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700897
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800898 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 out.writeInt(mCount);
900 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800901 out.writeInt(mUnpluggedCount);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800902 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 out.writeLong(mUnpluggedTime);
905 }
906
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800907 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800909 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 + " old mUnpluggedTime=" + mUnpluggedTime
911 + " old mUnpluggedCount=" + mUnpluggedCount);
912 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800913 mUnpluggedTime = computeRunTimeLocked(baseRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 mUnpluggedCount = mCount;
915 if (DEBUG && mType < 0) {
916 Log.v(TAG, "unplug #" + mType
917 + ": new mUnpluggedTime=" + mUnpluggedTime
918 + " new mUnpluggedCount=" + mUnpluggedCount);
919 }
920 }
921
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800922 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700923 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800924 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
Evan Millarc64edde2009-04-18 12:26:32 -0700925 + " old mTotalTime=" + mTotalTime);
926 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800927 mTotalTime = computeRunTimeLocked(baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -0700928 mCount = computeCurrentCountLocked();
929 if (DEBUG && mType < 0) {
930 Log.v(TAG, "plug #" + mType
931 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 }
933 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 /**
936 * Writes a possibly null Timer to a Parcel.
937 *
938 * @param out the Parcel to be written to.
939 * @param timer a Timer, or null.
940 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800941 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 if (timer == null) {
943 out.writeInt(0); // indicates null
944 return;
945 }
946 out.writeInt(1); // indicates non-null
947
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800948 timer.writeToParcel(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 }
950
951 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800952 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 long val;
954 if (which == STATS_LAST) {
955 val = mLastTime;
956 } else {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800957 val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700958 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 val -= mUnpluggedTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700960 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 val -= mLoadedTime;
962 }
963 }
964
965 return val;
966 }
967
968 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700969 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 int val;
971 if (which == STATS_LAST) {
972 val = mLastCount;
973 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700974 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700975 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700977 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 val -= mLoadedCount;
979 }
980 }
981
982 return val;
983 }
984
Dianne Hackborn627bba72009-03-24 22:32:56 -0700985 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -0700986 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
988 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700989 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700991 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700993 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700994
995
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800996 void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
997 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
998 out.writeLong(runTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700999 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -07001000 }
1001
1002 void readSummaryFromParcelLocked(Parcel in) {
1003 // Multiply by 1000 for backwards compatibility
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001004 mTotalTime = mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001005 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001006 mUnpluggedTime = mTotalTime;
1007 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001008 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001009 mUnpluggedCount = mCount;
1010 }
1011 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001012
Evan Millarc64edde2009-04-18 12:26:32 -07001013 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001014
Evan Millarc64edde2009-04-18 12:26:32 -07001015 /**
1016 * The most recent reported count from /proc/wakelocks.
1017 */
1018 int mCurrentReportedCount;
1019
1020 /**
1021 * The reported count from /proc/wakelocks when unplug() was last
1022 * called.
1023 */
1024 int mUnpluggedReportedCount;
1025
1026 /**
1027 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001028 */
Evan Millarc64edde2009-04-18 12:26:32 -07001029 long mCurrentReportedTotalTime;
1030
1031
1032 /**
1033 * The reported total_time from /proc/wakelocks when unplug() was last
1034 * called.
1035 */
1036 long mUnpluggedReportedTotalTime;
1037
1038 /**
1039 * Whether we are currently in a discharge cycle.
1040 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001041 boolean mTimeBaseRunning;
Evan Millarc64edde2009-04-18 12:26:32 -07001042
1043 /**
1044 * Whether we are currently recording reported values.
1045 */
1046 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001047
Evan Millarc64edde2009-04-18 12:26:32 -07001048 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001049 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -07001050 */
1051 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001052
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001053 SamplingTimer(TimeBase timeBase, Parcel in) {
1054 super(0, timeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07001055 mCurrentReportedCount = in.readInt();
1056 mUnpluggedReportedCount = in.readInt();
1057 mCurrentReportedTotalTime = in.readLong();
1058 mUnpluggedReportedTotalTime = in.readLong();
1059 mTrackingReportedValues = in.readInt() == 1;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001060 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001061 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001062
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001063 SamplingTimer(TimeBase timeBase, boolean trackReportedValues) {
1064 super(0, timeBase);
Evan Millarc64edde2009-04-18 12:26:32 -07001065 mTrackingReportedValues = trackReportedValues;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001066 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001067 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001068
Evan Millarc64edde2009-04-18 12:26:32 -07001069 public void setStale() {
1070 mTrackingReportedValues = false;
1071 mUnpluggedReportedTotalTime = 0;
1072 mUnpluggedReportedCount = 0;
1073 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001074
Evan Millarc64edde2009-04-18 12:26:32 -07001075 public void setUpdateVersion(int version) {
1076 mUpdateVersion = version;
1077 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001078
Evan Millarc64edde2009-04-18 12:26:32 -07001079 public int getUpdateVersion() {
1080 return mUpdateVersion;
1081 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001082
Evan Millarc64edde2009-04-18 12:26:32 -07001083 public void updateCurrentReportedCount(int count) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001084 if (mTimeBaseRunning && mUnpluggedReportedCount == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001085 // Updating the reported value for the first time.
1086 mUnpluggedReportedCount = count;
1087 // If we are receiving an update update mTrackingReportedValues;
1088 mTrackingReportedValues = true;
1089 }
1090 mCurrentReportedCount = count;
1091 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001092
Evan Millarc64edde2009-04-18 12:26:32 -07001093 public void updateCurrentReportedTotalTime(long totalTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001094 if (mTimeBaseRunning && mUnpluggedReportedTotalTime == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001095 // Updating the reported value for the first time.
1096 mUnpluggedReportedTotalTime = totalTime;
1097 // If we are receiving an update update mTrackingReportedValues;
1098 mTrackingReportedValues = true;
1099 }
1100 mCurrentReportedTotalTime = totalTime;
1101 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001102
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001103 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1104 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001105 if (mTrackingReportedValues) {
1106 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
1107 mUnpluggedReportedCount = mCurrentReportedCount;
1108 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001109 mTimeBaseRunning = true;
Evan Millarc64edde2009-04-18 12:26:32 -07001110 }
1111
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001112 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1113 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1114 mTimeBaseRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001115 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001116
Evan Millarc64edde2009-04-18 12:26:32 -07001117 public void logState(Printer pw, String prefix) {
1118 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001119 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -07001120 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
1121 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
1122 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
1123 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001124
Evan Millarc64edde2009-04-18 12:26:32 -07001125 protected long computeRunTimeLocked(long curBatteryRealtime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001126 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001127 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
1128 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001129
Evan Millarc64edde2009-04-18 12:26:32 -07001130 protected int computeCurrentCountLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001131 return mCount + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001132 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
1133 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001134
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001135 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1136 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001137 out.writeInt(mCurrentReportedCount);
1138 out.writeInt(mUnpluggedReportedCount);
1139 out.writeLong(mCurrentReportedTotalTime);
1140 out.writeLong(mUnpluggedReportedTotalTime);
1141 out.writeInt(mTrackingReportedValues ? 1 : 0);
1142 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001143
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001144 boolean reset(boolean detachIfReset) {
1145 super.reset(detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001146 setStale();
1147 return true;
1148 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001149
Evan Millarc64edde2009-04-18 12:26:32 -07001150 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
1151 super.writeSummaryFromParcelLocked(out, batteryRealtime);
1152 out.writeLong(mCurrentReportedTotalTime);
1153 out.writeInt(mCurrentReportedCount);
1154 out.writeInt(mTrackingReportedValues ? 1 : 0);
1155 }
1156
1157 void readSummaryFromParcelLocked(Parcel in) {
1158 super.readSummaryFromParcelLocked(in);
1159 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
1160 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
1161 mTrackingReportedValues = in.readInt() == 1;
1162 }
1163 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001164
Evan Millarc64edde2009-04-18 12:26:32 -07001165 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001166 * A timer that increments in batches. It does not run for durations, but just jumps
1167 * for a pre-determined amount.
1168 */
1169 public static final class BatchTimer extends Timer {
1170 final Uid mUid;
1171
1172 /**
1173 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
1174 */
1175 long mLastAddedTime;
1176
1177 /**
1178 * The last duration that we added to the timer. This is in microseconds.
1179 */
1180 long mLastAddedDuration;
1181
1182 /**
1183 * Whether we are currently in a discharge cycle.
1184 */
1185 boolean mInDischarge;
1186
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001187 BatchTimer(Uid uid, int type, TimeBase timeBase, Parcel in) {
1188 super(type, timeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001189 mUid = uid;
1190 mLastAddedTime = in.readLong();
1191 mLastAddedDuration = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001192 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001193 }
1194
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001195 BatchTimer(Uid uid, int type, TimeBase timeBase) {
1196 super(type, timeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001197 mUid = uid;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001198 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001199 }
1200
1201 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001202 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1203 super.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001204 out.writeLong(mLastAddedTime);
1205 out.writeLong(mLastAddedDuration);
1206 }
1207
1208 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001209 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001210 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
1211 mInDischarge = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001212 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001213 }
1214
1215 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001216 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001217 recomputeLastDuration(elapsedRealtime, false);
1218 mInDischarge = true;
1219 // If we are still within the last added duration, then re-added whatever remains.
1220 if (mLastAddedTime == elapsedRealtime) {
1221 mTotalTime += mLastAddedDuration;
1222 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001223 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001224 }
1225
1226 @Override
1227 public void logState(Printer pw, String prefix) {
1228 super.logState(pw, prefix);
1229 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
1230 + " mLastAddedDuration=" + mLastAddedDuration);
1231 }
1232
1233 private long computeOverage(long curTime) {
1234 if (mLastAddedTime > 0) {
1235 return mLastTime + mLastAddedDuration - curTime;
1236 }
1237 return 0;
1238 }
1239
1240 private void recomputeLastDuration(long curTime, boolean abort) {
1241 final long overage = computeOverage(curTime);
1242 if (overage > 0) {
1243 // Aborting before the duration ran out -- roll back the remaining
1244 // duration. Only do this if currently discharging; otherwise we didn't
1245 // actually add the time.
1246 if (mInDischarge) {
1247 mTotalTime -= overage;
1248 }
1249 if (abort) {
1250 mLastAddedTime = 0;
1251 } else {
1252 mLastAddedTime = curTime;
1253 mLastAddedDuration -= overage;
1254 }
1255 }
1256 }
1257
1258 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
1259 final long now = SystemClock.elapsedRealtime() * 1000;
1260 recomputeLastDuration(now, true);
1261 mLastAddedTime = now;
1262 mLastAddedDuration = durationMillis * 1000;
1263 if (mInDischarge) {
1264 mTotalTime += mLastAddedDuration;
1265 mCount++;
1266 }
1267 }
1268
1269 public void abortLastDuration(BatteryStatsImpl stats) {
1270 final long now = SystemClock.elapsedRealtime() * 1000;
1271 recomputeLastDuration(now, true);
1272 }
1273
1274 @Override
1275 protected int computeCurrentCountLocked() {
1276 return mCount;
1277 }
1278
1279 @Override
1280 protected long computeRunTimeLocked(long curBatteryRealtime) {
1281 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000);
1282 if (overage > 0) {
1283 return mTotalTime = overage;
1284 }
1285 return mTotalTime;
1286 }
1287
1288 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001289 boolean reset(boolean detachIfReset) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001290 final long now = SystemClock.elapsedRealtime() * 1000;
1291 recomputeLastDuration(now, true);
1292 boolean stillActive = mLastAddedTime == now;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001293 super.reset(!stillActive && detachIfReset);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001294 return !stillActive;
1295 }
1296 }
1297
1298 /**
Evan Millarc64edde2009-04-18 12:26:32 -07001299 * State for keeping track of timing information.
1300 */
1301 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001302 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07001303 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001304
Evan Millarc64edde2009-04-18 12:26:32 -07001305 int mNesting;
1306
Evan Millarc64edde2009-04-18 12:26:32 -07001307 /**
1308 * The last time at which we updated the timer. If mNesting is > 0,
1309 * subtract this from the current battery time to find the amount of
1310 * time we have been running since we last computed an update.
1311 */
1312 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001313
Evan Millarc64edde2009-04-18 12:26:32 -07001314 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001315 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -07001316 * was actually held for an interesting duration.
1317 */
1318 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001319
Amith Yamasanif37447b2009-10-08 18:28:01 -07001320 long mTimeout;
1321
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001322 /**
1323 * For partial wake locks, keep track of whether we are in the list
1324 * to consume CPU cycles.
1325 */
1326 boolean mInList;
1327
1328 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001329 TimeBase timeBase, Parcel in) {
1330 super(type, timeBase, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001331 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001332 mTimerPool = timerPool;
1333 mUpdateTime = in.readLong();
1334 }
1335
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001336 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001337 TimeBase timeBase) {
1338 super(type, timeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001339 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001340 mTimerPool = timerPool;
1341 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001342
Amith Yamasanif37447b2009-10-08 18:28:01 -07001343 void setTimeout(long timeout) {
1344 mTimeout = timeout;
1345 }
1346
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001347 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1348 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001349 out.writeLong(mUpdateTime);
1350 }
1351
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001352 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001353 if (mNesting > 0) {
1354 if (DEBUG && mType < 0) {
1355 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
1356 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001357 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1358 mUpdateTime = baseRealtime;
Evan Millarc64edde2009-04-18 12:26:32 -07001359 if (DEBUG && mType < 0) {
1360 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
1361 }
1362 }
1363 }
1364
1365 public void logState(Printer pw, String prefix) {
1366 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001367 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 + " mAcquireTime=" + mAcquireTime);
1369 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001370
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001371 void startRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 if (mNesting++ == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001373 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001374 mUpdateTime = batteryRealtime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 if (mTimerPool != null) {
1376 // Accumulate time to all currently active timers before adding
1377 // this new one to the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001378 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 // Add this timer to the active pool
1380 mTimerPool.add(this);
1381 }
1382 // Increment the count
1383 mCount++;
1384 mAcquireTime = mTotalTime;
1385 if (DEBUG && mType < 0) {
1386 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
1387 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1388 + " mAcquireTime=" + mAcquireTime);
1389 }
1390 }
1391 }
1392
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001393 boolean isRunningLocked() {
1394 return mNesting > 0;
1395 }
1396
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001397 long checkpointRunningLocked(long elapsedRealtimeMs) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001398 if (mNesting > 0) {
1399 // We are running...
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001400 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001401 if (mTimerPool != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001402 return refreshTimersLocked(batteryRealtime, mTimerPool, this);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001403 }
1404 final long heldTime = batteryRealtime - mUpdateTime;
1405 mUpdateTime = batteryRealtime;
1406 mTotalTime += heldTime;
1407 return heldTime;
1408 }
1409 return 0;
1410 }
1411
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001412 void stopRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 // Ignore attempt to stop a timer that isn't running
1414 if (mNesting == 0) {
1415 return;
1416 }
1417 if (--mNesting == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001418 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 if (mTimerPool != null) {
1420 // Accumulate time to all active counters, scaled by the total
1421 // active in the pool, before taking this one out of the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001422 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 // Remove this timer from the active pool
1424 mTimerPool.remove(this);
1425 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 mNesting = 1;
1427 mTotalTime = computeRunTimeLocked(batteryRealtime);
1428 mNesting = 0;
1429 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 if (DEBUG && mType < 0) {
1432 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
1433 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1434 + " mAcquireTime=" + mAcquireTime);
1435 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001437 if (mTotalTime == mAcquireTime) {
1438 // If there was no change in the time, then discard this
1439 // count. A somewhat cheezy strategy, but hey.
1440 mCount--;
1441 }
1442 }
1443 }
1444
1445 // Update the total time for all other running Timers with the same type as this Timer
1446 // due to a change in timer count
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001447 private static long refreshTimersLocked(long batteryRealtime,
1448 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001449 long selfTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450 final int N = pool.size();
1451 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07001452 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 long heldTime = batteryRealtime - t.mUpdateTime;
1454 if (heldTime > 0) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001455 final long myTime = heldTime / N;
1456 if (t == self) {
1457 selfTime = myTime;
1458 }
1459 t.mTotalTime += myTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 }
1461 t.mUpdateTime = batteryRealtime;
1462 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001463 return selfTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 }
1465
Evan Millarc64edde2009-04-18 12:26:32 -07001466 @Override
1467 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001468 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
1469 curBatteryRealtime = mUpdateTime + mTimeout;
1470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 return mTotalTime + (mNesting > 0
1472 ? (curBatteryRealtime - mUpdateTime)
1473 / (mTimerPool != null ? mTimerPool.size() : 1)
1474 : 0);
1475 }
1476
Evan Millarc64edde2009-04-18 12:26:32 -07001477 @Override
1478 protected int computeCurrentCountLocked() {
1479 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 }
1481
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001482 boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001483 boolean canDetach = mNesting <= 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001484 super.reset(canDetach && detachIfReset);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001485 if (mNesting > 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001486 mUpdateTime = mTimeBase.getRealtime(SystemClock.elapsedRealtime() * 1000);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001487 }
1488 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001489 return canDetach;
1490 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001491
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001492 void detach() {
1493 super.detach();
1494 if (mTimerPool != null) {
1495 mTimerPool.remove(this);
1496 }
1497 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001500 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 mNesting = 0;
1502 }
1503 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001504
Evan Millarc64edde2009-04-18 12:26:32 -07001505 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001506
Todd Poynor73f534a2012-06-19 11:07:26 -07001507 FileInputStream is;
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001508 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -07001509 int len;
Todd Poynor73f534a2012-06-19 11:07:26 -07001510 boolean wakeup_sources = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001511
Evan Millarc64edde2009-04-18 12:26:32 -07001512 try {
Todd Poynor73f534a2012-06-19 11:07:26 -07001513 try {
1514 is = new FileInputStream("/proc/wakelocks");
1515 } catch (java.io.FileNotFoundException e) {
1516 try {
1517 is = new FileInputStream("/d/wakeup_sources");
1518 wakeup_sources = true;
1519 } catch (java.io.FileNotFoundException e2) {
1520 return null;
Evan Millarc64edde2009-04-18 12:26:32 -07001521 }
1522 }
Todd Poynor73f534a2012-06-19 11:07:26 -07001523
1524 len = is.read(buffer);
1525 is.close();
Evan Millarc64edde2009-04-18 12:26:32 -07001526 } catch (java.io.IOException e) {
1527 return null;
1528 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001529
Todd Poynor73f534a2012-06-19 11:07:26 -07001530 if (len > 0) {
1531 int i;
1532 for (i=0; i<len; i++) {
1533 if (buffer[i] == '\0') {
1534 len = i;
1535 break;
1536 }
1537 }
1538 }
1539
1540 return parseProcWakelocks(buffer, len, wakeup_sources);
Evan Millarc64edde2009-04-18 12:26:32 -07001541 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001542
Evan Millarc64edde2009-04-18 12:26:32 -07001543 private final Map<String, KernelWakelockStats> parseProcWakelocks(
Todd Poynor73f534a2012-06-19 11:07:26 -07001544 byte[] wlBuffer, int len, boolean wakeup_sources) {
Evan Millarc64edde2009-04-18 12:26:32 -07001545 String name;
1546 int count;
1547 long totalTime;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001548 int startIndex;
1549 int endIndex;
Evan Millarc64edde2009-04-18 12:26:32 -07001550 int numUpdatedWlNames = 0;
1551
1552 // Advance past the first line.
1553 int i;
1554 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1555 startIndex = endIndex = i + 1;
1556
1557 synchronized(this) {
1558 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001559
Evan Millarc64edde2009-04-18 12:26:32 -07001560 sKernelWakelockUpdateVersion++;
1561 while (endIndex < len) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001562 for (endIndex=startIndex;
1563 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
Evan Millarc64edde2009-04-18 12:26:32 -07001564 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001565 endIndex++; // endIndex is an exclusive upper bound.
1566 // Don't go over the end of the buffer, Process.parseProcLine might
1567 // write to wlBuffer[endIndex]
1568 if (endIndex >= (len - 1) ) {
1569 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -07001570 }
Evan Millarc64edde2009-04-18 12:26:32 -07001571
1572 String[] nameStringArray = mProcWakelocksName;
1573 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001574 // Stomp out any bad characters since this is from a circular buffer
1575 // A corruption is seen sometimes that results in the vm crashing
1576 // This should prevent crashes and the line will probably fail to parse
1577 for (int j = startIndex; j < endIndex; j++) {
1578 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1579 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001580 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
Todd Poynor73f534a2012-06-19 11:07:26 -07001581 wakeup_sources ? WAKEUP_SOURCES_FORMAT :
1582 PROC_WAKELOCKS_FORMAT,
1583 nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001584
Evan Millarc64edde2009-04-18 12:26:32 -07001585 name = nameStringArray[0];
1586 count = (int) wlData[1];
Todd Poynor73f534a2012-06-19 11:07:26 -07001587
1588 if (wakeup_sources) {
1589 // convert milliseconds to microseconds
1590 totalTime = wlData[2] * 1000;
1591 } else {
1592 // convert nanoseconds to microseconds with rounding.
1593 totalTime = (wlData[2] + 500) / 1000;
1594 }
Evan Millarc64edde2009-04-18 12:26:32 -07001595
Amith Yamasani53b707b2009-09-30 11:05:30 -07001596 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001597 if (!m.containsKey(name)) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001598 m.put(name, new KernelWakelockStats(count, totalTime,
Evan Millarc64edde2009-04-18 12:26:32 -07001599 sKernelWakelockUpdateVersion));
1600 numUpdatedWlNames++;
1601 } else {
1602 KernelWakelockStats kwlStats = m.get(name);
1603 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1604 kwlStats.mCount += count;
1605 kwlStats.mTotalTime += totalTime;
1606 } else {
1607 kwlStats.mCount = count;
1608 kwlStats.mTotalTime = totalTime;
1609 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1610 numUpdatedWlNames++;
1611 }
1612 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001613 }
Evan Millarc64edde2009-04-18 12:26:32 -07001614 startIndex = endIndex;
1615 }
1616
1617 if (m.size() != numUpdatedWlNames) {
1618 // Don't report old data.
1619 Iterator<KernelWakelockStats> itr = m.values().iterator();
1620 while (itr.hasNext()) {
1621 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1622 itr.remove();
1623 }
1624 }
1625 }
1626 return m;
1627 }
1628 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001629
Evan Millarc64edde2009-04-18 12:26:32 -07001630 private class KernelWakelockStats {
1631 public int mCount;
1632 public long mTotalTime;
1633 public int mVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001634
Evan Millarc64edde2009-04-18 12:26:32 -07001635 KernelWakelockStats(int count, long totalTime, int version) {
1636 mCount = count;
1637 mTotalTime = totalTime;
1638 mVersion = version;
1639 }
1640 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001641
Evan Millarc64edde2009-04-18 12:26:32 -07001642 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001643 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001644 * doesn't already exist.
1645 */
1646 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1647 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1648 if (kwlt == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001649 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, true /* track reported values */);
Evan Millarc64edde2009-04-18 12:26:32 -07001650 mKernelWakelockStats.put(name, kwlt);
1651 }
1652 return kwlt;
1653 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001654
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001655 private int getCurrentBluetoothPingCount() {
1656 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001657 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1658 if (deviceList.size() > 0) {
1659 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001660 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001661 }
1662 return -1;
1663 }
1664
1665 public int getBluetoothPingCount() {
1666 if (mBluetoothPingStart == -1) {
1667 return mBluetoothPingCount;
1668 } else if (mBtHeadset != null) {
1669 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1670 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001671 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001672 }
1673
1674 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001675 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1676 mBluetoothPingStart = getCurrentBluetoothPingCount();
1677 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001678 mBtHeadset = headset;
1679 }
1680
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001681 private int writeHistoryTag(HistoryTag tag) {
1682 Integer idxObj = mHistoryTagPool.get(tag);
1683 int idx;
1684 if (idxObj != null) {
1685 idx = idxObj;
1686 } else {
1687 idx = mNextHistoryTagIdx;
1688 HistoryTag key = new HistoryTag();
1689 key.setTo(tag);
1690 tag.poolIdx = idx;
1691 mHistoryTagPool.put(key, idx);
1692 mNextHistoryTagIdx++;
1693 mNumHistoryTagChars += key.string.length() + 1;
1694 }
1695 return idx;
1696 }
1697
1698 private void readHistoryTag(int index, HistoryTag tag) {
1699 tag.string = mReadHistoryStrings[index];
1700 tag.uid = mReadHistoryUids[index];
1701 tag.poolIdx = index;
1702 }
1703
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001704 // Part of initial delta int that specifies the time delta.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001705 static final int DELTA_TIME_MASK = 0x7ffff;
1706 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
1707 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
1708 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001709 // Flag in delta int: a new battery level int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001710 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001711 // Flag in delta int: a new full state and battery status int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001712 static final int DELTA_STATE_FLAG = 0x00100000;
1713 // Flag in delta int: a new full state2 int follows.
1714 static final int DELTA_STATE2_FLAG = 0x00200000;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001715 // Flag in delta int: contains a wakelock or wakeReason tag.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001716 static final int DELTA_WAKELOCK_FLAG = 0x00400000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001717 // Flag in delta int: contains an event description.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001718 static final int DELTA_EVENT_FLAG = 0x00800000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001719 // These upper bits are the frequently changing state bits.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001720 static final int DELTA_STATE_MASK = 0xff000000;
1721
1722 // These are the pieces of battery state that are packed in to the upper bits of
1723 // the state int that have been packed in to the first delta int. They must fit
1724 // in DELTA_STATE_MASK.
1725 static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
1726 static final int STATE_BATTERY_STATUS_SHIFT = 29;
1727 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
1728 static final int STATE_BATTERY_HEALTH_SHIFT = 26;
1729 static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
1730 static final int STATE_BATTERY_PLUG_SHIFT = 24;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001731
1732 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001733 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001734 dest.writeInt(DELTA_TIME_ABS);
1735 cur.writeToParcel(dest, 0);
1736 return;
1737 }
1738
1739 final long deltaTime = cur.time - last.time;
1740 final int lastBatteryLevelInt = buildBatteryLevelInt(last);
1741 final int lastStateInt = buildStateInt(last);
1742
1743 int deltaTimeToken;
1744 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
1745 deltaTimeToken = DELTA_TIME_LONG;
1746 } else if (deltaTime >= DELTA_TIME_ABS) {
1747 deltaTimeToken = DELTA_TIME_INT;
1748 } else {
1749 deltaTimeToken = (int)deltaTime;
1750 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001751 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001752 final int batteryLevelInt = buildBatteryLevelInt(cur);
1753 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
1754 if (batteryLevelIntChanged) {
1755 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
1756 }
1757 final int stateInt = buildStateInt(cur);
1758 final boolean stateIntChanged = stateInt != lastStateInt;
1759 if (stateIntChanged) {
1760 firstToken |= DELTA_STATE_FLAG;
1761 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001762 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001763 firstToken |= DELTA_WAKELOCK_FLAG;
1764 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001765 if (cur.eventCode != HistoryItem.EVENT_NONE) {
1766 firstToken |= DELTA_EVENT_FLAG;
1767 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001768 dest.writeInt(firstToken);
1769 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
1770 + " deltaTime=" + deltaTime);
1771
1772 if (deltaTimeToken >= DELTA_TIME_INT) {
1773 if (deltaTimeToken == DELTA_TIME_INT) {
1774 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
1775 dest.writeInt((int)deltaTime);
1776 } else {
1777 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
1778 dest.writeLong(deltaTime);
1779 }
1780 }
1781 if (batteryLevelIntChanged) {
1782 dest.writeInt(batteryLevelInt);
1783 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
1784 + Integer.toHexString(batteryLevelInt)
1785 + " batteryLevel=" + cur.batteryLevel
1786 + " batteryTemp=" + cur.batteryTemperature
1787 + " batteryVolt=" + (int)cur.batteryVoltage);
1788 }
1789 if (stateIntChanged) {
1790 dest.writeInt(stateInt);
1791 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
1792 + Integer.toHexString(stateInt)
1793 + " batteryStatus=" + cur.batteryStatus
1794 + " batteryHealth=" + cur.batteryHealth
1795 + " batteryPlugType=" + cur.batteryPlugType
1796 + " states=0x" + Integer.toHexString(cur.states));
1797 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001798 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
1799 int wakeLockIndex;
1800 int wakeReasonIndex;
1801 if (cur.wakelockTag != null) {
1802 wakeLockIndex = writeHistoryTag(cur.wakelockTag);
1803 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
1804 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
1805 } else {
1806 wakeLockIndex = 0xffff;
1807 }
1808 if (cur.wakeReasonTag != null) {
1809 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
1810 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
1811 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
1812 } else {
1813 wakeReasonIndex = 0xffff;
1814 }
1815 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001816 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001817 if (cur.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001818 int index = writeHistoryTag(cur.eventTag);
1819 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
Dianne Hackborn099bc622014-01-22 13:39:16 -08001820 dest.writeInt(codeAndIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001821 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
1822 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
1823 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001824 }
1825 }
1826
1827 private int buildBatteryLevelInt(HistoryItem h) {
1828 return ((((int)h.batteryLevel)<<25)&0xfe000000)
1829 | ((((int)h.batteryTemperature)<<14)&0x01ffc000)
1830 | (((int)h.batteryVoltage)&0x00003fff);
1831 }
1832
1833 private int buildStateInt(HistoryItem h) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001834 int plugType = 0;
1835 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
1836 plugType = 1;
1837 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
1838 plugType = 2;
1839 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
1840 plugType = 3;
1841 }
1842 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
1843 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
1844 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001845 | (h.states&(~DELTA_STATE_MASK));
1846 }
1847
1848 public void readHistoryDelta(Parcel src, HistoryItem cur) {
1849 int firstToken = src.readInt();
1850 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001851 cur.cmd = HistoryItem.CMD_UPDATE;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001852 cur.numReadInts = 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001853 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
1854 + " deltaTimeToken=" + deltaTimeToken);
1855
1856 if (deltaTimeToken < DELTA_TIME_ABS) {
1857 cur.time += deltaTimeToken;
1858 } else if (deltaTimeToken == DELTA_TIME_ABS) {
1859 cur.time = src.readLong();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001860 cur.numReadInts += 2;
1861 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001862 cur.readFromParcel(src);
1863 return;
1864 } else if (deltaTimeToken == DELTA_TIME_INT) {
1865 int delta = src.readInt();
1866 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001867 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001868 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
1869 } else {
1870 long delta = src.readLong();
1871 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
1872 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001873 cur.numReadInts += 2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001874 }
1875
1876 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
1877 int batteryLevelInt = src.readInt();
1878 cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
1879 cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21);
1880 cur.batteryVoltage = (char)(batteryLevelInt&0x3fff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001881 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001882 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
1883 + Integer.toHexString(batteryLevelInt)
1884 + " batteryLevel=" + cur.batteryLevel
1885 + " batteryTemp=" + cur.batteryTemperature
1886 + " batteryVolt=" + (int)cur.batteryVoltage);
1887 }
1888
1889 if ((firstToken&DELTA_STATE_FLAG) != 0) {
1890 int stateInt = src.readInt();
1891 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001892 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
1893 & STATE_BATTERY_STATUS_MASK);
1894 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
1895 & STATE_BATTERY_HEALTH_MASK);
1896 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
1897 & STATE_BATTERY_PLUG_MASK);
1898 switch (cur.batteryPlugType) {
1899 case 1:
1900 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
1901 break;
1902 case 2:
1903 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
1904 break;
1905 case 3:
1906 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
1907 break;
1908 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001909 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001910 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
1911 + Integer.toHexString(stateInt)
1912 + " batteryStatus=" + cur.batteryStatus
1913 + " batteryHealth=" + cur.batteryHealth
1914 + " batteryPlugType=" + cur.batteryPlugType
1915 + " states=0x" + Integer.toHexString(cur.states));
1916 } else {
1917 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK));
1918 }
1919
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001920 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001921 int indexes = src.readInt();
1922 int wakeLockIndex = indexes&0xffff;
1923 int wakeReasonIndex = (indexes>>16)&0xffff;
1924 if (wakeLockIndex != 0xffff) {
1925 cur.wakelockTag = cur.localWakelockTag;
1926 readHistoryTag(wakeLockIndex, cur.wakelockTag);
1927 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
1928 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
1929 } else {
1930 cur.wakelockTag = null;
1931 }
1932 if (wakeReasonIndex != 0xffff) {
1933 cur.wakeReasonTag = cur.localWakeReasonTag;
1934 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
1935 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
1936 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
1937 } else {
1938 cur.wakeReasonTag = null;
1939 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001940 cur.numReadInts += 1;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001941 } else {
1942 cur.wakelockTag = null;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001943 cur.wakeReasonTag = null;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001944 }
1945
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001946 if ((firstToken&DELTA_EVENT_FLAG) != 0) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001947 cur.eventTag = cur.localEventTag;
1948 final int codeAndIndex = src.readInt();
Dianne Hackborn099bc622014-01-22 13:39:16 -08001949 cur.eventCode = (codeAndIndex&0xffff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001950 final int index = ((codeAndIndex>>16)&0xffff);
1951 readHistoryTag(index, cur.eventTag);
1952 cur.numReadInts += 1;
1953 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
1954 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
1955 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001956 } else {
1957 cur.eventCode = HistoryItem.EVENT_NONE;
1958 }
1959 }
1960
Dianne Hackborn40c87252014-03-19 16:55:40 -07001961 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001962 if (!mHaveBatteryLevel || !mRecordingHistory) {
1963 return;
1964 }
1965
Dianne Hackborn40c87252014-03-19 16:55:40 -07001966 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001967 final int diffStates = mHistoryLastWritten.states^mHistoryCur.states;
1968 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
1969 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
1970 + Integer.toHexString(diffStates) + " lastDiff="
1971 + Integer.toHexString(lastDiffStates));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001972 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001973 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
1974 && (mHistoryLastWritten.wakelockTag == null || mHistoryCur.wakelockTag == null)
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001975 && (mHistoryLastWritten.wakeReasonTag == null || mHistoryCur.wakeReasonTag == null)
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001976 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
1977 || mHistoryCur.eventCode == HistoryItem.EVENT_NONE)
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001978 && mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel
1979 && mHistoryLastWritten.batteryStatus == mHistoryCur.batteryStatus
1980 && mHistoryLastWritten.batteryHealth == mHistoryCur.batteryHealth
1981 && mHistoryLastWritten.batteryPlugType == mHistoryCur.batteryPlugType
1982 && mHistoryLastWritten.batteryTemperature == mHistoryCur.batteryTemperature
1983 && mHistoryLastWritten.batteryVoltage == mHistoryCur.batteryVoltage) {
1984 // We can merge this new change in with the last one. Merging is
Dianne Hackborn40c87252014-03-19 16:55:40 -07001985 // allowed as long as only the states have changed, and within those states
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001986 // as long as no bit has changed both between now and the last entry, as
1987 // well as the last entry and the one before it (so we capture any toggles).
1988 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001989 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
1990 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
1991 mHistoryBufferLastPos = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07001992 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001993 // If the last written history had a wakelock tag, we need to retain it.
1994 // Note that the condition above made sure that we aren't in a case where
1995 // both it and the current history item have a wakelock tag.
1996 if (mHistoryLastWritten.wakelockTag != null) {
1997 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
1998 mHistoryCur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
1999 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002000 // If the last written history had a wake reason tag, we need to retain it.
2001 // Note that the condition above made sure that we aren't in a case where
2002 // both it and the current history item have a wakelock tag.
2003 if (mHistoryLastWritten.wakeReasonTag != null) {
2004 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
2005 mHistoryCur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
2006 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002007 // If the last written history had an event, we need to retain it.
2008 // Note that the condition above made sure that we aren't in a case where
2009 // both it and the current history item have an event.
2010 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
2011 mHistoryCur.eventCode = mHistoryLastWritten.eventCode;
2012 mHistoryCur.eventTag = mHistoryCur.localEventTag;
2013 mHistoryCur.eventTag.setTo(mHistoryLastWritten.eventTag);
2014 }
Dianne Hackborn1fadab52011-04-14 17:57:33 -07002015 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002016 }
2017
2018 final int dataSize = mHistoryBuffer.dataSize();
2019 if (dataSize >= MAX_HISTORY_BUFFER) {
2020 if (!mHistoryOverflow) {
2021 mHistoryOverflow = true;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002022 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE);
2023 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002024 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002025 }
2026
2027 // Once we've reached the maximum number of items, we only
2028 // record changes to the battery level and the most interesting states.
2029 // Once we've reached the maximum maximum number of items, we only
2030 // record changes to the battery level.
2031 if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
2032 (dataSize >= MAX_MAX_HISTORY_BUFFER
Amith Yamasani45f06462011-11-21 16:08:34 -08002033 || ((mHistoryLastWritten.states^mHistoryCur.states)
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002034 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
2035 return;
2036 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002037
Dianne Hackborn40c87252014-03-19 16:55:40 -07002038 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002039 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002040 }
2041
Dianne Hackborn40c87252014-03-19 16:55:40 -07002042 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002043 }
2044
Dianne Hackborn40c87252014-03-19 16:55:40 -07002045 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002046 if (mIteratingHistory) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002047 throw new IllegalStateException("Can't do this while iterating history!");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002048 }
2049 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
2050 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07002051 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, mHistoryCur);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002052 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07002053 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
2054 mLastHistoryUptime = uptimeMs;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002055 mHistoryCur.wakelockTag = null;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002056 mHistoryCur.wakeReasonTag = null;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002057 mHistoryCur.eventCode = HistoryItem.EVENT_NONE;
2058 mHistoryCur.eventTag = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002059 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
2060 + " now " + mHistoryBuffer.dataPosition()
2061 + " size is now " + mHistoryBuffer.dataSize());
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002062 }
2063
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002064 int mChangedStates = 0;
2065
Dianne Hackborn40c87252014-03-19 16:55:40 -07002066 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
2067 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002068
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002069 if (!USE_OLD_HISTORY) {
2070 return;
2071 }
2072
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002073 if (!mHaveBatteryLevel || !mRecordingHistory) {
2074 return;
2075 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002076
2077 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002078 // and no states have since the last recorded entry changed and
2079 // are now resetting back to their original value, then just collapse
2080 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002081 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002082 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002083 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002084 // If the current is the same as the one before, then we no
2085 // longer need the entry.
2086 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002087 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002088 && mHistoryLastEnd.sameNonEvent(mHistoryCur)) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002089 mHistoryLastEnd.next = null;
2090 mHistoryEnd.next = mHistoryCache;
2091 mHistoryCache = mHistoryEnd;
2092 mHistoryEnd = mHistoryLastEnd;
2093 mHistoryLastEnd = null;
2094 } else {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002095 mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002096 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002097 }
2098 return;
2099 }
2100
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002101 mChangedStates = 0;
2102
2103 if (mNumHistoryItems == MAX_HISTORY_ITEMS
2104 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002105 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002106 }
2107
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002108 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
2109 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002110 // record changes to the battery level and the most interesting states.
2111 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002112 // record changes to the battery level.
2113 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002114 == mHistoryCur.batteryLevel &&
2115 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
2116 || ((mHistoryEnd.states^mHistoryCur.states)
2117 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002118 return;
2119 }
2120 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002121
Dianne Hackborn40c87252014-03-19 16:55:40 -07002122 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002123 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002124
Dianne Hackborn40c87252014-03-19 16:55:40 -07002125 void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
2126 String name, int uid) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002127 mHistoryCur.eventCode = code;
2128 mHistoryCur.eventTag = mHistoryCur.localEventTag;
2129 mHistoryCur.eventTag.string = name;
2130 mHistoryCur.eventTag.uid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002131 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002132 }
2133
Dianne Hackborn40c87252014-03-19 16:55:40 -07002134 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002135 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002136 if (rec != null) {
2137 mHistoryCache = rec.next;
2138 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002139 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002140 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07002141 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, mHistoryCur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002142
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002143 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002144 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002145
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002146 void addHistoryRecordLocked(HistoryItem rec) {
2147 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002148 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002149 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002150 if (mHistoryEnd != null) {
2151 mHistoryEnd.next = rec;
2152 mHistoryEnd = rec;
2153 } else {
2154 mHistory = mHistoryEnd = rec;
2155 }
2156 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002157
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002158 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002159 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002160 if (USE_OLD_HISTORY) {
2161 if (mHistory != null) {
2162 mHistoryEnd.next = mHistoryCache;
2163 mHistoryCache = mHistory;
2164 mHistory = mHistoryLastEnd = mHistoryEnd = null;
2165 }
2166 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002167 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002168
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002169 mHistoryBaseTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002170 mLastHistoryElapsedRealtime = 0;
2171 mLastHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002172
2173 mHistoryBuffer.setDataSize(0);
2174 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002175 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002176 mHistoryLastLastWritten.clear();
2177 mHistoryLastWritten.clear();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002178 mHistoryTagPool.clear();
2179 mNextHistoryTagIdx = 0;
2180 mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002181 mHistoryBufferLastPos = -1;
2182 mHistoryOverflow = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002183 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002184
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002185 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
2186 long realtime) {
2187 if (mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime)) {
2188 if (unplugged) {
2189 // Track bt headset ping count
2190 mBluetoothPingStart = getCurrentBluetoothPingCount();
2191 mBluetoothPingCount = 0;
2192 } else {
2193 // Track bt headset ping count
2194 mBluetoothPingCount = getBluetoothPingCount();
2195 mBluetoothPingStart = -1;
2196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002197 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002198
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002199 boolean unpluggedScreenOff = unplugged && screenOff;
2200 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
2201 updateKernelWakelocksLocked();
2202 requestWakelockCpuUpdate();
2203 if (!unpluggedScreenOff) {
2204 // We are switching to no longer tracking wake locks, but we want
2205 // the next CPU update we receive to take them in to account.
2206 mDistributeWakelockCpu = true;
2207 }
2208 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 }
2210 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002211
Dianne Hackborn099bc622014-01-22 13:39:16 -08002212 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
2213 mIsolatedUids.put(isolatedUid, appUid);
2214 }
2215
2216 public void removeIsolatedUidLocked(int isolatedUid, int appUid) {
2217 int curUid = mIsolatedUids.get(isolatedUid, -1);
2218 if (curUid == appUid) {
2219 mIsolatedUids.delete(isolatedUid);
2220 }
2221 }
2222
2223 public int mapUid(int uid) {
2224 int isolated = mIsolatedUids.get(uid, -1);
2225 return isolated > 0 ? isolated : uid;
2226 }
2227
2228 public void noteEventLocked(int code, String name, int uid) {
2229 uid = mapUid(uid);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002230 if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
2231 int idx = code&~HistoryItem.EVENT_FLAG_START;
2232 HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
2233 if (active == null) {
2234 active = new HashMap<String, SparseBooleanArray>();
2235 mActiveEvents[idx] = active;
2236 }
2237 SparseBooleanArray uids = active.get(name);
2238 if (uids == null) {
2239 uids = new SparseBooleanArray();
2240 active.put(name, uids);
2241 }
2242 if (uids.get(uid)) {
2243 // Already set, nothing to do!
2244 return;
2245 }
2246 uids.put(uid, true);
2247 } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
2248 int idx = code&~HistoryItem.EVENT_FLAG_FINISH;
2249 HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
2250 if (active == null) {
2251 // not currently active, nothing to do.
2252 return;
2253 }
2254 SparseBooleanArray uids = active.get(name);
2255 if (uids == null) {
2256 // not currently active, nothing to do.
2257 return;
2258 }
2259 idx = uids.indexOfKey(uid);
2260 if (idx < 0 || !uids.valueAt(idx)) {
2261 // not currently active, nothing to do.
2262 return;
2263 }
2264 uids.removeAt(idx);
2265 if (uids.size() <= 0) {
2266 active.remove(name);
2267 }
2268 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07002269 final long elapsedRealtime = SystemClock.elapsedRealtime();
2270 final long uptime = SystemClock.uptimeMillis();
2271 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002272 }
2273
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002274 private void requestWakelockCpuUpdate() {
2275 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
2276 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
2277 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
2278 }
2279 }
2280
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002281 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002282 boolean unimportantForLogging, long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002283 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002284 if (type == WAKE_TYPE_PARTIAL) {
2285 // Only care about partial wake locks, since full wake locks
2286 // will be canceled when the user puts the screen to sleep.
2287 if (mWakeLockNesting == 0) {
2288 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
2289 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
2290 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002291 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002292 mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002293 mHistoryCur.wakelockTag.uid = uid;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002294 mWakeLockImportant = !unimportantForLogging;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002295 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002296 } else if (!mWakeLockImportant && !unimportantForLogging) {
2297 if (mHistoryLastWritten.wakelockTag != null) {
2298 // We'll try to update the last tag.
2299 mHistoryLastWritten.wakelockTag = null;
2300 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002301 mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002302 mHistoryCur.wakelockTag.uid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002303 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002304 }
2305 mWakeLockImportant = true;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002306 }
2307 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002308 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002309 if (uid >= 0) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002310 //if (uid == 0) {
2311 // Slog.wtf(TAG, "Acquiring wake lock from root: " + name);
2312 //}
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002313 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002314 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002315 }
2316 }
2317
Dianne Hackborn40c87252014-03-19 16:55:40 -07002318 public void noteStopWakeLocked(int uid, int pid, String name, int type, long elapsedRealtime,
2319 long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002320 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002321 if (type == WAKE_TYPE_PARTIAL) {
2322 mWakeLockNesting--;
2323 if (mWakeLockNesting == 0) {
2324 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
2325 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
2326 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002327 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002328 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002329 }
2330 if (uid >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002331 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002332 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002333 }
2334 }
2335
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002336 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
2337 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002338 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002339 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002340 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002341 for (int i=0; i<N; i++) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002342 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002343 elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002344 }
2345 }
2346
2347 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, int type,
2348 WorkSource newWs, int newPid, String newName,
2349 String newHistoryName, int newType, boolean newUnimportantForLogging) {
2350 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002351 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002352 // For correct semantics, we start the need worksources first, so that we won't
2353 // make inappropriate history items as if all wake locks went away and new ones
2354 // appeared. This is okay because tracking of wake locks allows nesting.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002355 final int NN = newWs.size();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002356 for (int i=0; i<NN; i++) {
2357 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002358 newUnimportantForLogging, elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002359 }
2360 final int NO = ws.size();
2361 for (int i=0; i<NO; i++) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002362 noteStopWakeLocked(ws.get(i), pid, name, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002363 }
2364 }
2365
2366 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002367 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002368 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002369 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002370 for (int i=0; i<N; i++) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002371 noteStopWakeLocked(ws.get(i), pid, name, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002372 }
2373 }
2374
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002375 public void noteWakeupReasonLocked(int irq, String reason) {
2376 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002377 final long uptime = SystemClock.uptimeMillis();
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002378 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason irq #" + irq + "\"" + reason +"\": "
2379 + Integer.toHexString(mHistoryCur.states));
2380 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
2381 mHistoryCur.wakeReasonTag.string = reason;
2382 mHistoryCur.wakeReasonTag.uid = irq;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002383 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002384 }
2385
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002386 public int startAddingCpuLocked() {
2387 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2388
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002389 final int N = mPartialTimers.size();
2390 if (N == 0) {
2391 mLastPartialTimers.clear();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002392 mDistributeWakelockCpu = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002393 return 0;
2394 }
2395
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002396 if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) {
2397 return 0;
2398 }
2399
2400 mDistributeWakelockCpu = false;
2401
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002402 // How many timers should consume CPU? Only want to include ones
2403 // that have already been in the list.
2404 for (int i=0; i<N; i++) {
2405 StopwatchTimer st = mPartialTimers.get(i);
2406 if (st.mInList) {
2407 Uid uid = st.mUid;
2408 // We don't include the system UID, because it so often
2409 // holds wake locks at one request or another of an app.
2410 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2411 return 50;
2412 }
2413 }
2414 }
2415
2416 return 0;
2417 }
2418
2419 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
2420 final int N = mPartialTimers.size();
2421 if (perc != 0) {
2422 int num = 0;
2423 for (int i=0; i<N; i++) {
2424 StopwatchTimer st = mPartialTimers.get(i);
2425 if (st.mInList) {
2426 Uid uid = st.mUid;
2427 // We don't include the system UID, because it so often
2428 // holds wake locks at one request or another of an app.
2429 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2430 num++;
2431 }
2432 }
2433 }
2434 if (num != 0) {
2435 for (int i=0; i<N; i++) {
2436 StopwatchTimer st = mPartialTimers.get(i);
2437 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002438 Uid uid = st.mUid;
2439 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07002440 int myUTime = utime/num;
2441 int mySTime = stime/num;
2442 utime -= myUTime;
2443 stime -= mySTime;
2444 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002445 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
2446 proc.addCpuTimeLocked(myUTime, mySTime);
2447 proc.addSpeedStepTimes(cpuSpeedTimes);
2448 }
2449 }
2450 }
2451 }
2452
2453 // Just in case, collect any lost CPU time.
2454 if (utime != 0 || stime != 0) {
2455 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
2456 if (uid != null) {
2457 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
2458 proc.addCpuTimeLocked(utime, stime);
2459 proc.addSpeedStepTimes(cpuSpeedTimes);
2460 }
2461 }
2462 }
2463
2464 final int NL = mLastPartialTimers.size();
2465 boolean diff = N != NL;
2466 for (int i=0; i<NL && !diff; i++) {
2467 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
2468 }
2469 if (!diff) {
2470 for (int i=0; i<NL; i++) {
2471 mPartialTimers.get(i).mInList = true;
2472 }
2473 return;
2474 }
2475
2476 for (int i=0; i<NL; i++) {
2477 mLastPartialTimers.get(i).mInList = false;
2478 }
2479 mLastPartialTimers.clear();
2480 for (int i=0; i<N; i++) {
2481 StopwatchTimer st = mPartialTimers.get(i);
2482 st.mInList = true;
2483 mLastPartialTimers.add(st);
2484 }
2485 }
2486
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002487 public void noteProcessDiedLocked(int uid, int pid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002488 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002489 Uid u = mUidStats.get(uid);
2490 if (u != null) {
2491 u.mPids.remove(pid);
2492 }
2493 }
2494
2495 public long getProcessWakeTime(int uid, int pid, long realtime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002496 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002497 Uid u = mUidStats.get(uid);
2498 if (u != null) {
2499 Uid.Pid p = u.mPids.get(pid);
2500 if (p != null) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002501 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002502 }
2503 }
2504 return 0;
2505 }
2506
2507 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002508 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002509 Uid u = mUidStats.get(uid);
2510 if (u != null) {
2511 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
2512 }
2513 }
2514
Dianne Hackborn287952c2010-09-22 22:34:31 -07002515 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002516 uid = mapUid(uid);
Dianne Hackborn287952c2010-09-22 22:34:31 -07002517 Uid u = mUidStats.get(uid);
2518 if (u != null) {
2519 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
2520 }
2521 }
2522
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002523 int mSensorNesting;
2524
2525 public void noteStartSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002526 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002527 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002528 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002529 if (mSensorNesting == 0) {
2530 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
2531 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
2532 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002533 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002534 }
2535 mSensorNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002536 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002537 }
2538
2539 public void noteStopSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002540 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002541 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002542 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002543 mSensorNesting--;
2544 if (mSensorNesting == 0) {
2545 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
2546 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
2547 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002548 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002549 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002550 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002551 }
2552
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002553 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002554
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002555 public void noteStartGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002556 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002557 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002558 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002559 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002560 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002561 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
2562 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002563 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002564 }
2565 mGpsNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002566 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002568
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002569 public void noteStopGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002570 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002571 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002572 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002573 mGpsNesting--;
2574 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002575 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002576 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
2577 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002578 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002579 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002580 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 public void noteScreenOnLocked() {
2584 if (!mScreenOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002585 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002586 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002587 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002588 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
2589 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002590 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 mScreenOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002592 mScreenOnTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002593 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002594 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002595 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002596
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002597 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false,
2598 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
2599
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002600 // Fake a wake lock, so we consider the device waked as long
2601 // as the screen is on.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002602 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
2603 elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002604
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08002605 // Update discharge amounts.
2606 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08002607 updateDischargeScreenLevelsLocked(false, true);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08002608 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002609 }
2610 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 public void noteScreenOffLocked() {
2613 if (mScreenOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002614 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002615 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002616 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002617 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
2618 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002619 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620 mScreenOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002621 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002622 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002623 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002624 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002625
Dianne Hackborn40c87252014-03-19 16:55:40 -07002626 noteStopWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL,
2627 elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002628
2629 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
2630 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
2631
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08002632 // Update discharge amounts.
2633 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08002634 updateDischargeScreenLevelsLocked(true, false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08002635 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002636 }
2637 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002638
Dianne Hackborn617f8772009-03-31 15:04:46 -07002639 public void noteScreenBrightnessLocked(int brightness) {
2640 // Bin the brightness.
2641 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
2642 if (bin < 0) bin = 0;
2643 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
2644 if (mScreenBrightnessBin != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002645 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002646 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002647 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
2648 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002649 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
2650 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002651 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002652 if (mScreenOn) {
2653 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002654 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002655 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002656 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002657 }
2658 mScreenBrightnessBin = bin;
2659 }
2660 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002661
Christopher Tate4cee7252010-03-19 14:50:40 -07002662 public void noteInputEventAtomic() {
2663 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002664 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002665
Dianne Hackborn617f8772009-03-31 15:04:46 -07002666 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002667 if (mOnBatteryInternal) {
2668 uid = mapUid(uid);
2669 getUidStatsLocked(uid).noteUserActivityLocked(event);
2670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002672
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002673 public void noteDataConnectionActive(int type, boolean active) {
2674 if (ConnectivityManager.isNetworkTypeMobile(type)) {
2675 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002676 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002677 if (mMobileRadioActive != active) {
2678 if (active) mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
2679 else mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
2680 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
2681 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002682 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002683 mMobileRadioActive = active;
2684 if (active) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002685 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
2686 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002687 } else {
2688 updateNetworkActivityLocked(NET_UPDATE_MOBILE, elapsedRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002689 mMobileRadioActiveTimer.stopRunningLocked(elapsedRealtime);
2690 mMobileRadioActivePerAppTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002691 }
2692 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002693 }
2694 }
2695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 public void notePhoneOnLocked() {
2697 if (!mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002698 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002699 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002700 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002701 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
2702 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002703 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 mPhoneOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002705 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002706 }
2707 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 public void notePhoneOffLocked() {
2710 if (mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002711 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002712 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002713 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002714 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
2715 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002716 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002717 mPhoneOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002718 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 }
2720 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002721
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002722 void stopAllSignalStrengthTimersLocked(int except) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002723 final long elapsedRealtime = SystemClock.elapsedRealtime();
Wink Saville52840902011-02-18 12:40:47 -08002724 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002725 if (i == except) {
2726 continue;
2727 }
2728 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002729 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002730 }
2731 }
2732 }
2733
Dianne Hackborne4a59512010-12-07 11:08:07 -08002734 private int fixPhoneServiceState(int state, int signalBin) {
2735 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
2736 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2737 // to infer that we are scanning from other data.
2738 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08002739 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002740 state = ServiceState.STATE_IN_SERVICE;
2741 }
2742 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002743
Dianne Hackborne4a59512010-12-07 11:08:07 -08002744 return state;
2745 }
2746
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002747 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002748 boolean scanning = false;
2749 boolean newHistory = false;
2750
2751 mPhoneServiceStateRaw = state;
2752 mPhoneSimStateRaw = simState;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002753 mPhoneSignalStrengthBinRaw = strengthBin;
2754
2755 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002756 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne4a59512010-12-07 11:08:07 -08002757
2758 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
2759 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2760 // to infer that we are scanning from other data.
2761 if (state == ServiceState.STATE_OUT_OF_SERVICE
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002762 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002763 state = ServiceState.STATE_IN_SERVICE;
2764 }
2765 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002766
2767 // If the phone is powered off, stop all timers.
2768 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002769 strengthBin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002770
Dianne Hackborne4a59512010-12-07 11:08:07 -08002771 // If we are in service, make sure the correct signal string timer is running.
2772 } else if (state == ServiceState.STATE_IN_SERVICE) {
2773 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002774
2775 // If we're out of service, we are in the lowest signal strength
2776 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07002777 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002778 scanning = true;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002779 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002780 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002781 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08002782 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002783 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
2784 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002785 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
Amith Yamasanif37447b2009-10-08 18:28:01 -07002786 }
2787 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002788
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002789 if (!scanning) {
2790 // If we are no longer scanning, then stop the scanning timer.
2791 if (mPhoneSignalScanningTimer.isRunningLocked()) {
2792 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
2793 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
2794 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002795 newHistory = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002796 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002797 }
2798 }
2799
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002800 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002801 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
2802 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002803 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002804 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002805 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002806 mPhoneServiceState = state;
2807 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08002808
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002809 if (mPhoneSignalStrengthBin != strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002810 if (mPhoneSignalStrengthBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002811 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002812 elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002813 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002814 if (strengthBin >= 0) {
2815 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002816 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002817 }
2818 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002819 | (strengthBin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
2820 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
Dianne Hackborne4a59512010-12-07 11:08:07 -08002821 + Integer.toHexString(mHistoryCur.states));
2822 newHistory = true;
2823 } else {
2824 stopAllSignalStrengthTimersLocked(-1);
2825 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002826 mPhoneSignalStrengthBin = strengthBin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08002827 }
2828
2829 if (newHistory) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002830 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002831 }
2832 }
2833
2834 /**
2835 * Telephony stack updates the phone state.
2836 * @param state phone state from ServiceState.getState()
2837 */
2838 public void notePhoneStateLocked(int state, int simState) {
2839 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002840 }
2841
Wink Savillee9b06d72009-05-18 21:47:50 -07002842 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07002843 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08002844 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08002845 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002846 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002847
Dianne Hackborn627bba72009-03-24 22:32:56 -07002848 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
2849 int bin = DATA_CONNECTION_NONE;
2850 if (hasData) {
2851 switch (dataType) {
2852 case TelephonyManager.NETWORK_TYPE_EDGE:
2853 bin = DATA_CONNECTION_EDGE;
2854 break;
2855 case TelephonyManager.NETWORK_TYPE_GPRS:
2856 bin = DATA_CONNECTION_GPRS;
2857 break;
2858 case TelephonyManager.NETWORK_TYPE_UMTS:
2859 bin = DATA_CONNECTION_UMTS;
2860 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002861 case TelephonyManager.NETWORK_TYPE_CDMA:
2862 bin = DATA_CONNECTION_CDMA;
2863 break;
2864 case TelephonyManager.NETWORK_TYPE_EVDO_0:
2865 bin = DATA_CONNECTION_EVDO_0;
2866 break;
2867 case TelephonyManager.NETWORK_TYPE_EVDO_A:
2868 bin = DATA_CONNECTION_EVDO_A;
2869 break;
2870 case TelephonyManager.NETWORK_TYPE_1xRTT:
2871 bin = DATA_CONNECTION_1xRTT;
2872 break;
2873 case TelephonyManager.NETWORK_TYPE_HSDPA:
2874 bin = DATA_CONNECTION_HSDPA;
2875 break;
2876 case TelephonyManager.NETWORK_TYPE_HSUPA:
2877 bin = DATA_CONNECTION_HSUPA;
2878 break;
2879 case TelephonyManager.NETWORK_TYPE_HSPA:
2880 bin = DATA_CONNECTION_HSPA;
2881 break;
2882 case TelephonyManager.NETWORK_TYPE_IDEN:
2883 bin = DATA_CONNECTION_IDEN;
2884 break;
2885 case TelephonyManager.NETWORK_TYPE_EVDO_B:
2886 bin = DATA_CONNECTION_EVDO_B;
2887 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07002888 case TelephonyManager.NETWORK_TYPE_LTE:
2889 bin = DATA_CONNECTION_LTE;
2890 break;
2891 case TelephonyManager.NETWORK_TYPE_EHRPD:
2892 bin = DATA_CONNECTION_EHRPD;
2893 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08002894 case TelephonyManager.NETWORK_TYPE_HSPAP:
2895 bin = DATA_CONNECTION_HSPAP;
2896 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07002897 default:
2898 bin = DATA_CONNECTION_OTHER;
2899 break;
2900 }
2901 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002902 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002903 if (mPhoneDataConnectionType != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002904 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002905 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002906 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
2907 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002908 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
2909 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002910 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002911 if (mPhoneDataConnectionType >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002912 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002913 elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002914 }
2915 mPhoneDataConnectionType = bin;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002916 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002917 }
2918 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002919
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002920 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002921 if (!mWifiOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002922 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002923 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002924 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002925 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
2926 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002927 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07002928 mWifiOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002929 mWifiOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07002930 }
2931 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002932
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002933 public void noteWifiOffLocked() {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002934 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002935 final long uptime = SystemClock.uptimeMillis();
The Android Open Source Project10592532009-03-18 17:39:46 -07002936 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002937 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002938 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
2939 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002940 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07002941 mWifiOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002942 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07002943 }
2944 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002945
2946 public void noteAudioOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002947 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002948 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002949 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002950 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002951 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002952 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
2953 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002954 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002955 mAudioOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002956 mAudioOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002957 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002958 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002959 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002960
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002961 public void noteAudioOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002962 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002963 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002964 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002965 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002966 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002967 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
2968 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002969 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002970 mAudioOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002971 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002972 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002973 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002974 }
2975
2976 public void noteVideoOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002977 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002978 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002979 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002980 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002981 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002982 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
2983 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002984 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002985 mVideoOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002986 mVideoOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002987 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002988 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002989 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002990
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002991 public void noteVideoOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002992 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002993 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002994 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002995 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002996 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002997 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
2998 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002999 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003000 mVideoOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003001 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003002 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003003 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003004 }
3005
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003006 public void noteActivityResumedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003007 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003008 getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003009 }
3010
3011 public void noteActivityPausedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003012 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003013 getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003014 }
3015
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003016 public void noteVibratorOnLocked(int uid, long durationMillis) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003017 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003018 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
3019 }
3020
3021 public void noteVibratorOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003022 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003023 getUidStatsLocked(uid).noteVibratorOffLocked();
3024 }
3025
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003026 public void noteWifiRunningLocked(WorkSource ws) {
3027 if (!mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003028 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003029 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003030 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003031 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
3032 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003033 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003034 mGlobalWifiRunning = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003035 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003036 int N = ws.size();
3037 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003038 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003039 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003040 }
3041 } else {
3042 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003043 }
3044 }
3045
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003046 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
3047 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003048 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003049 int N = oldWs.size();
3050 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003051 int uid = mapUid(oldWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003052 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003053 }
3054 N = newWs.size();
3055 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003056 int uid = mapUid(newWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003057 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003058 }
3059 } else {
3060 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
3061 }
3062 }
3063
3064 public void noteWifiStoppedLocked(WorkSource ws) {
3065 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003066 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003067 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003068 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003069 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
3070 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003071 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003072 mGlobalWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003073 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003074 int N = ws.size();
3075 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003076 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003077 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003078 }
3079 } else {
3080 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003081 }
3082 }
3083
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003084 public void noteWifiStateLocked(int wifiState, String accessPoint) {
3085 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
3086 if (mWifiState != wifiState) {
3087 final long elapsedRealtime = SystemClock.elapsedRealtime();
3088 if (mWifiState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003089 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003090 }
3091 mWifiState = wifiState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003092 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003093 }
3094 }
3095
The Android Open Source Project10592532009-03-18 17:39:46 -07003096 public void noteBluetoothOnLocked() {
3097 if (!mBluetoothOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003098 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003099 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003100 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003101 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
3102 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003103 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003104 mBluetoothOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003105 mBluetoothOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003106 }
3107 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003108
The Android Open Source Project10592532009-03-18 17:39:46 -07003109 public void noteBluetoothOffLocked() {
3110 if (mBluetoothOn) {
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 Hackborn6b7b4842010-06-14 17:17:44 -07003113 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003114 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
3115 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003116 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003117 mBluetoothOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003118 mBluetoothOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003119 }
3120 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003121
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003122 public void noteBluetoothStateLocked(int bluetoothState) {
3123 if (DEBUG) Log.i(TAG, "Bluetooth state -> " + bluetoothState);
3124 if (mBluetoothState != bluetoothState) {
3125 final long elapsedRealtime = SystemClock.elapsedRealtime();
3126 if (mBluetoothState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003127 mBluetoothStateTimer[mBluetoothState].stopRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003128 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003129 mBluetoothState = bluetoothState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003130 mBluetoothStateTimer[bluetoothState].startRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003131 }
3132 }
3133
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003134 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003135
The Android Open Source Project10592532009-03-18 17:39:46 -07003136 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003137 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003138 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003139 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003140 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003141 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003142 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
3143 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003144 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003145 }
3146 mWifiFullLockNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003147 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003148 }
3149
3150 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003151 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003152 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003153 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003154 mWifiFullLockNesting--;
3155 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003156 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003157 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
3158 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003159 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003160 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003161 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003162 }
3163
Nick Pelly6ccaa542012-06-15 15:22:47 -07003164 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003165
Nick Pelly6ccaa542012-06-15 15:22:47 -07003166 public void noteWifiScanStartedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003167 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003168 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003169 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003170 if (mWifiScanNesting == 0) {
3171 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
3172 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003173 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003174 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003175 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003176 mWifiScanNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003177 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003178 }
3179
Nick Pelly6ccaa542012-06-15 15:22:47 -07003180 public void noteWifiScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003181 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003182 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003183 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003184 mWifiScanNesting--;
3185 if (mWifiScanNesting == 0) {
3186 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
3187 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003188 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003189 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003190 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003191 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003192 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003193
Robert Greenwalta029ea12013-09-25 16:38:12 -07003194 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003195 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003196 final long elapsedRealtime = SystemClock.elapsedRealtime();
3197 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003198 }
3199
3200 public void noteWifiBatchedScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003201 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003202 final long elapsedRealtime = SystemClock.elapsedRealtime();
3203 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003204 }
3205
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003206 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003207
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003208 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003209 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003210 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003211 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003212 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003213 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003214 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
3215 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003216 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003217 }
3218 mWifiMulticastNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003219 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003220 }
3221
3222 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003223 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003224 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003225 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003226 mWifiMulticastNesting--;
3227 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003228 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003229 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
3230 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003231 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003232 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003233 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003234 }
3235
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003236 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
3237 int N = ws.size();
3238 for (int i=0; i<N; i++) {
3239 noteFullWifiLockAcquiredLocked(ws.get(i));
3240 }
3241 }
3242
3243 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
3244 int N = ws.size();
3245 for (int i=0; i<N; i++) {
3246 noteFullWifiLockReleasedLocked(ws.get(i));
3247 }
3248 }
3249
Nick Pelly6ccaa542012-06-15 15:22:47 -07003250 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003251 int N = ws.size();
3252 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003253 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003254 }
3255 }
3256
Nick Pelly6ccaa542012-06-15 15:22:47 -07003257 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003258 int N = ws.size();
3259 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003260 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003261 }
3262 }
3263
Robert Greenwalta029ea12013-09-25 16:38:12 -07003264 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
3265 int N = ws.size();
3266 for (int i=0; i<N; i++) {
3267 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
3268 }
3269 }
3270
3271 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
3272 int N = ws.size();
3273 for (int i=0; i<N; i++) {
3274 noteWifiBatchedScanStoppedLocked(ws.get(i));
3275 }
3276 }
3277
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003278 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
3279 int N = ws.size();
3280 for (int i=0; i<N; i++) {
3281 noteWifiMulticastEnabledLocked(ws.get(i));
3282 }
3283 }
3284
3285 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
3286 int N = ws.size();
3287 for (int i=0; i<N; i++) {
3288 noteWifiMulticastDisabledLocked(ws.get(i));
3289 }
3290 }
3291
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003292 private static String[] includeInStringArray(String[] array, String str) {
3293 if (ArrayUtils.indexOf(array, str) >= 0) {
3294 return array;
3295 }
3296 String[] newArray = new String[array.length+1];
3297 System.arraycopy(array, 0, newArray, 0, array.length);
3298 newArray[array.length] = str;
3299 return newArray;
3300 }
3301
3302 private static String[] excludeFromStringArray(String[] array, String str) {
3303 int index = ArrayUtils.indexOf(array, str);
3304 if (index >= 0) {
3305 String[] newArray = new String[array.length-1];
3306 if (index > 0) {
3307 System.arraycopy(array, 0, newArray, 0, index);
3308 }
3309 if (index < array.length-1) {
3310 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
3311 }
3312 return newArray;
3313 }
3314 return array;
3315 }
3316
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003317 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
3318 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003319 mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
3320 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003321 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003322 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
3323 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003324 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003325 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003326 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
3327 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003328 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003329 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
3330 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003331 }
3332 }
3333
3334 public void noteNetworkStatsEnabledLocked() {
3335 // During device boot, qtaguid isn't enabled until after the inital
3336 // loading of battery stats. Now that they're enabled, take our initial
3337 // snapshot for future delta calculation.
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003338 updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003339 }
3340
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003341 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
3342 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003344
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003345 @Override public int getScreenOnCount(int which) {
3346 return mScreenOnTimer.getCountLocked(which);
3347 }
3348
Dianne Hackborn617f8772009-03-31 15:04:46 -07003349 @Override public long getScreenBrightnessTime(int brightnessBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003350 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003351 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003352 elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003353 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003354
Dianne Hackborn617f8772009-03-31 15:04:46 -07003355 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003356 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003357 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003358
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003359 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
3360 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003361 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003362
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003363 @Override public int getPhoneOnCount(int which) {
3364 return mPhoneOnTimer.getCountLocked(which);
3365 }
3366
Dianne Hackborn627bba72009-03-24 22:32:56 -07003367 @Override public long getPhoneSignalStrengthTime(int strengthBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003368 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003369 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003370 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003371 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003372
3373 @Override public long getPhoneSignalScanningTime(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003374 long elapsedRealtimeUs, int which) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07003375 return mPhoneSignalScanningTimer.getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003376 elapsedRealtimeUs, which);
Amith Yamasanif37447b2009-10-08 18:28:01 -07003377 }
3378
Catherine Liufb900812012-07-17 14:12:56 -05003379 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
3380 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003381 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003382
Dianne Hackborn627bba72009-03-24 22:32:56 -07003383 @Override public long getPhoneDataConnectionTime(int dataType,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003384 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003385 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003386 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003387 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003388
Dianne Hackborn617f8772009-03-31 15:04:46 -07003389 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003390 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003391 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003392
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003393 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
3394 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003395 }
3396
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003397 @Override public int getMobileRadioActiveCount(int which) {
3398 return mMobileRadioActiveTimer.getCountLocked(which);
3399 }
3400
3401 @Override public long getMobileRadioActiveUnknownTime(int which) {
3402 return mMobileRadioActiveUnknownTime.getCountLocked(which);
3403 }
3404
3405 @Override public int getMobileRadioActiveUnknownCount(int which) {
3406 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
3407 }
3408
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003409 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
3410 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003411 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003412
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003413 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
3414 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003415 }
3416
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003417 @Override public long getWifiStateTime(int wifiState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003418 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003419 return mWifiStateTimer[wifiState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003420 elapsedRealtimeUs, which);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003421 }
3422
3423 @Override public int getWifiStateCount(int wifiState, int which) {
3424 return mWifiStateTimer[wifiState].getCountLocked(which);
3425 }
3426
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003427 @Override public long getBluetoothOnTime(long elapsedRealtimeUs, int which) {
3428 return mBluetoothOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003429 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003430
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003431 @Override public long getBluetoothStateTime(int bluetoothState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003432 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003433 return mBluetoothStateTimer[bluetoothState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003434 elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003435 }
3436
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003437 @Override public int getBluetoothStateCount(int bluetoothState, int which) {
3438 return mBluetoothStateTimer[bluetoothState].getCountLocked(which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003439 }
3440
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003441 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003442 public long getNetworkActivityBytes(int type, int which) {
3443 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
3444 return mNetworkByteActivityCounters[type].getCountLocked(which);
3445 } else {
3446 return 0;
3447 }
3448 }
3449
3450 @Override
3451 public long getNetworkActivityPackets(int type, int which) {
3452 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
3453 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003454 } else {
3455 return 0;
3456 }
3457 }
3458
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08003459 @Override public long getStartClockTime() {
3460 return mStartClockTime;
3461 }
3462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003463 @Override public boolean getIsOnBattery() {
3464 return mOnBattery;
3465 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003467 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
3468 return mUidStats;
3469 }
3470
3471 /**
3472 * The statistics associated with a particular uid.
3473 */
3474 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003476 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003477
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003478 boolean mWifiRunning;
3479 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003480
The Android Open Source Project10592532009-03-18 17:39:46 -07003481 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07003482 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003483
Nick Pelly6ccaa542012-06-15 15:22:47 -07003484 boolean mWifiScanStarted;
3485 StopwatchTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003486
Robert Greenwalta029ea12013-09-25 16:38:12 -07003487 private static final int NO_BATCHED_SCAN_STARTED = -1;
3488 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
3489 StopwatchTimer[] mWifiBatchedScanTimer;
3490
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003491 boolean mWifiMulticastEnabled;
3492 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003493
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003494 boolean mAudioTurnedOn;
3495 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003496
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003497 boolean mVideoTurnedOn;
3498 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003499
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003500 StopwatchTimer mForegroundActivityTimer;
3501
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003502 BatchTimer mVibratorOnTimer;
3503
Dianne Hackborn617f8772009-03-31 15:04:46 -07003504 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003505
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003506 LongSamplingCounter[] mNetworkByteActivityCounters;
3507 LongSamplingCounter[] mNetworkPacketActivityCounters;
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003508 LongSamplingCounter mMobileRadioActiveTime;
3509 LongSamplingCounter mMobileRadioActiveCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003511 /**
3512 * The statistics we have collected for this uid's wake locks.
3513 */
3514 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
3515
3516 /**
3517 * The statistics we have collected for this uid's sensor activations.
3518 */
3519 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
3520
3521 /**
3522 * The statistics we have collected for this uid's processes.
3523 */
3524 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
3525
3526 /**
3527 * The statistics we have collected for this uid's processes.
3528 */
3529 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003530
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003531 /**
3532 * The transient wake stats we have collected for this uid's pids.
3533 */
3534 final SparseArray<Pid> mPids = new SparseArray<Pid>();
3535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003536 public Uid(int uid) {
3537 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003538 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003539 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003540 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003541 mFullWifiLockTimers, mOnBatteryTimeBase);
Nick Pelly6ccaa542012-06-15 15:22:47 -07003542 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003543 mWifiScanTimers, mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003544 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003545 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003546 mWifiMulticastTimers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003547 }
3548
3549 @Override
3550 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
3551 return mWakelockStats;
3552 }
3553
3554 @Override
3555 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
3556 return mSensorStats;
3557 }
3558
3559 @Override
3560 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
3561 return mProcessStats;
3562 }
3563
3564 @Override
3565 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
3566 return mPackageStats;
3567 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003568
3569 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003570 public int getUid() {
3571 return mUid;
3572 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003573
3574 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003575 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003576 if (!mWifiRunning) {
3577 mWifiRunning = true;
3578 if (mWifiRunningTimer == null) {
3579 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003580 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003581 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003582 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003583 }
3584 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003585
Dianne Hackborn617f8772009-03-31 15:04:46 -07003586 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003587 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003588 if (mWifiRunning) {
3589 mWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003590 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003591 }
3592 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003593
Dianne Hackborn617f8772009-03-31 15:04:46 -07003594 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003595 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003596 if (!mFullWifiLockOut) {
3597 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003598 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003599 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003600 mFullWifiLockTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003601 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003602 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003603 }
3604 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003605
The Android Open Source Project10592532009-03-18 17:39:46 -07003606 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003607 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003608 if (mFullWifiLockOut) {
3609 mFullWifiLockOut = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003610 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003611 }
3612 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003613
The Android Open Source Project10592532009-03-18 17:39:46 -07003614 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003615 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003616 if (!mWifiScanStarted) {
3617 mWifiScanStarted = true;
3618 if (mWifiScanTimer == null) {
3619 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003620 mWifiScanTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003621 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003622 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003623 }
3624 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003625
The Android Open Source Project10592532009-03-18 17:39:46 -07003626 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003627 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003628 if (mWifiScanStarted) {
3629 mWifiScanStarted = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003630 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003631 }
3632 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003633
3634 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003635 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07003636 int bin = 0;
3637 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
3638 csph = csph >> 3;
3639 bin++;
3640 }
3641
3642 if (mWifiBatchedScanBinStarted == bin) return;
3643
3644 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
3645 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003646 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003647 }
3648 mWifiBatchedScanBinStarted = bin;
3649 if (mWifiBatchedScanTimer[bin] == null) {
3650 makeWifiBatchedScanBin(bin, null);
3651 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003652 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003653 }
3654
3655 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003656 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07003657 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
3658 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003659 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003660 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
3661 }
3662 }
3663
3664 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003665 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003666 if (!mWifiMulticastEnabled) {
3667 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003668 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003669 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003670 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003671 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003672 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003673 }
3674 }
3675
3676 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003677 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003678 if (mWifiMulticastEnabled) {
3679 mWifiMulticastEnabled = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003680 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003681 }
3682 }
3683
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003684 public StopwatchTimer createAudioTurnedOnTimerLocked() {
3685 if (mAudioTurnedOnTimer == null) {
3686 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003687 null, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003688 }
3689 return mAudioTurnedOnTimer;
3690 }
3691
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003692 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003693 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003694 if (!mAudioTurnedOn) {
3695 mAudioTurnedOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003696 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003697 }
3698 }
3699
3700 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003701 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003702 if (mAudioTurnedOn) {
3703 mAudioTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003704 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003705 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003706 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003707 }
3708 }
3709
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003710 public StopwatchTimer createVideoTurnedOnTimerLocked() {
3711 if (mVideoTurnedOnTimer == null) {
3712 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003713 null, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003714 }
3715 return mVideoTurnedOnTimer;
3716 }
3717
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003718 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003719 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003720 if (!mVideoTurnedOn) {
3721 mVideoTurnedOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003722 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003723 }
3724 }
3725
3726 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003727 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003728 if (mVideoTurnedOn) {
3729 mVideoTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003730 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003731 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003732 }
3733 }
3734 }
3735
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003736 public StopwatchTimer createForegroundActivityTimerLocked() {
3737 if (mForegroundActivityTimer == null) {
3738 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003739 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003740 }
3741 return mForegroundActivityTimer;
3742 }
3743
3744 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003745 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003746 // We always start, since we want multiple foreground PIDs to nest
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003747 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003748 }
3749
3750 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003751 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003752 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003753 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003754 }
3755 }
3756
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003757 public BatchTimer createVibratorOnTimerLocked() {
3758 if (mVibratorOnTimer == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003759 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003760 }
3761 return mVibratorOnTimer;
3762 }
3763
3764 public void noteVibratorOnLocked(long durationMillis) {
3765 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
3766 }
3767
3768 public void noteVibratorOffLocked() {
3769 if (mVibratorOnTimer != null) {
3770 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003771 }
3772 }
3773
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003774 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003775 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003776 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003777 return 0;
3778 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003779 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003780 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003781
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003782 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003783 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003784 if (mFullWifiLockTimer == null) {
3785 return 0;
3786 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003787 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003788 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003789
3790 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003791 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003792 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003793 return 0;
3794 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003795 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003796 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003797
3798 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003799 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07003800 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
3801 if (mWifiBatchedScanTimer[csphBin] == null) {
3802 return 0;
3803 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003804 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003805 }
3806
3807 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003808 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003809 if (mWifiMulticastTimer == null) {
3810 return 0;
3811 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003812 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003813 }
3814
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003815 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003816 public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003817 if (mAudioTurnedOnTimer == null) {
3818 return 0;
3819 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003820 return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003821 }
3822
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003823 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003824 public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003825 if (mVideoTurnedOnTimer == null) {
3826 return 0;
3827 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003828 return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003829 }
3830
Dianne Hackborn617f8772009-03-31 15:04:46 -07003831 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003832 public Timer getForegroundActivityTimer() {
3833 return mForegroundActivityTimer;
3834 }
3835
3836 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003837 public Timer getVibratorOnTimer() {
3838 return mVibratorOnTimer;
3839 }
3840
3841 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07003842 public void noteUserActivityLocked(int type) {
3843 if (mUserActivityCounters == null) {
3844 initUserActivityLocked();
3845 }
Jeff Browndf693de2012-07-27 12:03:38 -07003846 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
3847 mUserActivityCounters[type].stepAtomic();
3848 } else {
3849 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
3850 new Throwable());
3851 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07003852 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003853
Dianne Hackborn617f8772009-03-31 15:04:46 -07003854 @Override
3855 public boolean hasUserActivity() {
3856 return mUserActivityCounters != null;
3857 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003858
Dianne Hackborn617f8772009-03-31 15:04:46 -07003859 @Override
3860 public int getUserActivityCount(int type, int which) {
3861 if (mUserActivityCounters == null) {
3862 return 0;
3863 }
Evan Millarc64edde2009-04-18 12:26:32 -07003864 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003865 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003866
Robert Greenwalta029ea12013-09-25 16:38:12 -07003867 void makeWifiBatchedScanBin(int i, Parcel in) {
3868 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
3869
3870 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i);
3871 if (collected == null) {
3872 collected = new ArrayList<StopwatchTimer>();
3873 mWifiBatchedScanTimers.put(i, collected);
3874 }
3875 if (in == null) {
3876 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003877 mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003878 } else {
3879 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003880 mOnBatteryTimeBase, in);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003881 }
3882 }
3883
3884
Dianne Hackborn617f8772009-03-31 15:04:46 -07003885 void initUserActivityLocked() {
3886 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
3887 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003888 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003889 }
3890 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003891
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003892 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
3893 if (mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003894 initNetworkActivityLocked();
3895 }
3896 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003897 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
3898 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003899 } else {
3900 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
3901 new Throwable());
3902 }
3903 }
3904
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003905 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
3906 if (mNetworkByteActivityCounters == null) {
3907 initNetworkActivityLocked();
3908 }
3909 mMobileRadioActiveTime.addCountLocked(batteryUptime);
3910 mMobileRadioActiveCount.addCountLocked(1);
3911 }
3912
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003913 @Override
3914 public boolean hasNetworkActivity() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003915 return mNetworkByteActivityCounters != null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003916 }
3917
3918 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003919 public long getNetworkActivityBytes(int type, int which) {
3920 if (mNetworkByteActivityCounters != null && type >= 0
3921 && type < mNetworkByteActivityCounters.length) {
3922 return mNetworkByteActivityCounters[type].getCountLocked(which);
3923 } else {
3924 return 0;
3925 }
3926 }
3927
3928 @Override
3929 public long getNetworkActivityPackets(int type, int which) {
3930 if (mNetworkPacketActivityCounters != null && type >= 0
3931 && type < mNetworkPacketActivityCounters.length) {
3932 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003933 } else {
3934 return 0;
3935 }
3936 }
3937
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003938 @Override
3939 public long getMobileRadioActiveTime(int which) {
3940 return mMobileRadioActiveTime != null
3941 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
3942 }
3943
3944 @Override
3945 public int getMobileRadioActiveCount(int which) {
3946 return mMobileRadioActiveCount != null
3947 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
3948 }
3949
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003950 void initNetworkActivityLocked() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003951 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
3952 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003953 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003954 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
3955 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003956 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003957 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase);
3958 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003960
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003961 /**
3962 * Clear all stats for this uid. Returns true if the uid is completely
3963 * inactive so can be dropped.
3964 */
3965 boolean reset() {
3966 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003967
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003968 if (mWifiRunningTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003969 active |= !mWifiRunningTimer.reset(false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003970 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003971 }
3972 if (mFullWifiLockTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003973 active |= !mFullWifiLockTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003974 active |= mFullWifiLockOut;
3975 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003976 if (mWifiScanTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003977 active |= !mWifiScanTimer.reset(false);
Nick Pelly6ccaa542012-06-15 15:22:47 -07003978 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003979 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07003980 if (mWifiBatchedScanTimer != null) {
3981 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
3982 if (mWifiBatchedScanTimer[i] != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003983 active |= !mWifiBatchedScanTimer[i].reset(false);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003984 }
3985 }
3986 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
3987 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003988 if (mWifiMulticastTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003989 active |= !mWifiMulticastTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003990 active |= mWifiMulticastEnabled;
3991 }
3992 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003993 active |= !mAudioTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003994 active |= mAudioTurnedOn;
3995 }
3996 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003997 active |= !mVideoTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003998 active |= mVideoTurnedOn;
3999 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004000 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004001 active |= !mForegroundActivityTimer.reset(false);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004002 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004003 if (mVibratorOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004004 if (mVibratorOnTimer.reset(false)) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004005 mVibratorOnTimer.detach();
4006 mVibratorOnTimer = null;
4007 } else {
4008 active = true;
4009 }
4010 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004011
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004012 if (mUserActivityCounters != null) {
4013 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
4014 mUserActivityCounters[i].reset(false);
4015 }
4016 }
4017
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004018 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004019 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004020 mNetworkByteActivityCounters[i].reset(false);
4021 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004022 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004023 mMobileRadioActiveTime.reset(false);
4024 mMobileRadioActiveCount.reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004025 }
4026
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004027 if (mWakelockStats.size() > 0) {
4028 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
4029 while (it.hasNext()) {
4030 Map.Entry<String, Wakelock> wakelockEntry = it.next();
4031 Wakelock wl = wakelockEntry.getValue();
4032 if (wl.reset()) {
4033 it.remove();
4034 } else {
4035 active = true;
4036 }
4037 }
4038 }
4039 if (mSensorStats.size() > 0) {
4040 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
4041 while (it.hasNext()) {
4042 Map.Entry<Integer, Sensor> sensorEntry = it.next();
4043 Sensor s = sensorEntry.getValue();
4044 if (s.reset()) {
4045 it.remove();
4046 } else {
4047 active = true;
4048 }
4049 }
4050 }
4051 if (mProcessStats.size() > 0) {
4052 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
4053 while (it.hasNext()) {
4054 Map.Entry<String, Proc> procEntry = it.next();
4055 procEntry.getValue().detach();
4056 }
4057 mProcessStats.clear();
4058 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004059 if (mPids.size() > 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004060 for (int i=mPids.size()-1; i>=0; i--) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004061 Pid pid = mPids.valueAt(i);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004062 if (pid.mWakeNesting > 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004063 active = true;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004064 } else {
4065 mPids.removeAt(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004066 }
4067 }
4068 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004069 if (mPackageStats.size() > 0) {
4070 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
4071 while (it.hasNext()) {
4072 Map.Entry<String, Pkg> pkgEntry = it.next();
4073 Pkg p = pkgEntry.getValue();
4074 p.detach();
4075 if (p.mServiceStats.size() > 0) {
4076 Iterator<Map.Entry<String, Pkg.Serv>> it2
4077 = p.mServiceStats.entrySet().iterator();
4078 while (it2.hasNext()) {
4079 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
4080 servEntry.getValue().detach();
4081 }
4082 }
4083 }
4084 mPackageStats.clear();
4085 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004086
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004087 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004088 if (mWifiRunningTimer != null) {
4089 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004090 }
4091 if (mFullWifiLockTimer != null) {
4092 mFullWifiLockTimer.detach();
4093 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004094 if (mWifiScanTimer != null) {
4095 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004096 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004097 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4098 if (mWifiBatchedScanTimer[i] != null) {
4099 mWifiBatchedScanTimer[i].detach();
4100 }
4101 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004102 if (mWifiMulticastTimer != null) {
4103 mWifiMulticastTimer.detach();
4104 }
4105 if (mAudioTurnedOnTimer != null) {
4106 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004107 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004108 }
4109 if (mVideoTurnedOnTimer != null) {
4110 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004111 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004112 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004113 if (mForegroundActivityTimer != null) {
4114 mForegroundActivityTimer.detach();
4115 mForegroundActivityTimer = null;
4116 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004117 if (mUserActivityCounters != null) {
4118 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
4119 mUserActivityCounters[i].detach();
4120 }
4121 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004122 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004123 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004124 mNetworkByteActivityCounters[i].detach();
4125 mNetworkPacketActivityCounters[i].detach();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004126 }
4127 }
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004128 mPids.clear();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004129 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004130
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004131 return !active;
4132 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004133
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004134 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004135 out.writeInt(mWakelockStats.size());
4136 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
4137 out.writeString(wakelockEntry.getKey());
4138 Uid.Wakelock wakelock = wakelockEntry.getValue();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004139 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004140 }
4141
4142 out.writeInt(mSensorStats.size());
4143 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
4144 out.writeInt(sensorEntry.getKey());
4145 Uid.Sensor sensor = sensorEntry.getValue();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004146 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004147 }
4148
4149 out.writeInt(mProcessStats.size());
4150 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
4151 out.writeString(procEntry.getKey());
4152 Uid.Proc proc = procEntry.getValue();
4153 proc.writeToParcelLocked(out);
4154 }
4155
4156 out.writeInt(mPackageStats.size());
4157 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
4158 out.writeString(pkgEntry.getKey());
4159 Uid.Pkg pkg = pkgEntry.getValue();
4160 pkg.writeToParcelLocked(out);
4161 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004162
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004163 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004164 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004165 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004166 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004167 out.writeInt(0);
4168 }
4169 if (mFullWifiLockTimer != null) {
4170 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004171 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004172 } else {
4173 out.writeInt(0);
4174 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004175 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004176 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004177 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004178 } else {
4179 out.writeInt(0);
4180 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004181 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4182 if (mWifiBatchedScanTimer[i] != null) {
4183 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004184 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004185 } else {
4186 out.writeInt(0);
4187 }
4188 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004189 if (mWifiMulticastTimer != null) {
4190 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004191 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004192 } else {
4193 out.writeInt(0);
4194 }
4195 if (mAudioTurnedOnTimer != null) {
4196 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004197 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004198 } else {
4199 out.writeInt(0);
4200 }
4201 if (mVideoTurnedOnTimer != null) {
4202 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004203 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004204 } else {
4205 out.writeInt(0);
4206 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004207 if (mForegroundActivityTimer != null) {
4208 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004209 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004210 } else {
4211 out.writeInt(0);
4212 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004213 if (mVibratorOnTimer != null) {
4214 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004215 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004216 } else {
4217 out.writeInt(0);
4218 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004219 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07004220 out.writeInt(1);
4221 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
4222 mUserActivityCounters[i].writeToParcel(out);
4223 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004224 } else {
4225 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004226 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004227 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004228 out.writeInt(1);
4229 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004230 mNetworkByteActivityCounters[i].writeToParcel(out);
4231 mNetworkPacketActivityCounters[i].writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004232 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004233 mMobileRadioActiveTime.writeToParcel(out);
4234 mMobileRadioActiveCount.writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004235 } else {
4236 out.writeInt(0);
4237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 }
4239
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004240 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 int numWakelocks = in.readInt();
4242 mWakelockStats.clear();
4243 for (int j = 0; j < numWakelocks; j++) {
4244 String wakelockName = in.readString();
4245 Uid.Wakelock wakelock = new Wakelock();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004246 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
Dianne Hackbornc24ab862011-10-18 15:55:03 -07004247 // We will just drop some random set of wakelocks if
4248 // the previous run of the system was an older version
4249 // that didn't impose a limit.
4250 mWakelockStats.put(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004251 }
4252
4253 int numSensors = in.readInt();
4254 mSensorStats.clear();
4255 for (int k = 0; k < numSensors; k++) {
4256 int sensorNumber = in.readInt();
4257 Uid.Sensor sensor = new Sensor(sensorNumber);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004258 sensor.readFromParcelLocked(mOnBatteryTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004259 mSensorStats.put(sensorNumber, sensor);
4260 }
4261
4262 int numProcs = in.readInt();
4263 mProcessStats.clear();
4264 for (int k = 0; k < numProcs; k++) {
4265 String processName = in.readString();
4266 Uid.Proc proc = new Proc();
4267 proc.readFromParcelLocked(in);
4268 mProcessStats.put(processName, proc);
4269 }
4270
4271 int numPkgs = in.readInt();
4272 mPackageStats.clear();
4273 for (int l = 0; l < numPkgs; l++) {
4274 String packageName = in.readString();
4275 Uid.Pkg pkg = new Pkg();
4276 pkg.readFromParcelLocked(in);
4277 mPackageStats.put(packageName, pkg);
4278 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004279
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004280 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004281 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004282 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004283 mWifiRunningTimers, mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004284 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004285 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004286 }
4287 mFullWifiLockOut = false;
4288 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004289 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004290 mFullWifiLockTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004291 } else {
4292 mFullWifiLockTimer = null;
4293 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004294 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004295 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004296 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004297 mWifiScanTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004298 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004299 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004300 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004301 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4302 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4303 if (in.readInt() != 0) {
4304 makeWifiBatchedScanBin(i, in);
4305 } else {
4306 mWifiBatchedScanTimer[i] = null;
4307 }
4308 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004309 mWifiMulticastEnabled = false;
4310 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004311 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004312 mWifiMulticastTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004313 } else {
4314 mWifiMulticastTimer = null;
4315 }
4316 mAudioTurnedOn = false;
4317 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004318 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004319 null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004320 } else {
4321 mAudioTurnedOnTimer = null;
4322 }
4323 mVideoTurnedOn = false;
4324 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004325 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004326 null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004327 } else {
4328 mVideoTurnedOnTimer = null;
4329 }
4330 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004331 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004332 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004333 } else {
4334 mForegroundActivityTimer = null;
4335 }
4336 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004337 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004338 } else {
4339 mVibratorOnTimer = null;
4340 }
4341 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07004342 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
4343 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004344 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004345 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004346 } else {
4347 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07004348 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004349 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004350 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
4351 mNetworkPacketActivityCounters
4352 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004353 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004354 mNetworkByteActivityCounters[i]
4355 = new LongSamplingCounter(mOnBatteryTimeBase, in);
4356 mNetworkPacketActivityCounters[i]
4357 = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004358 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004359 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
4360 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004361 } else {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004362 mNetworkByteActivityCounters = null;
4363 mNetworkPacketActivityCounters = null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004365 }
4366
4367 /**
4368 * The statistics associated with a particular wake lock.
4369 */
4370 public final class Wakelock extends BatteryStats.Uid.Wakelock {
4371 /**
4372 * How long (in ms) this uid has been keeping the device partially awake.
4373 */
Evan Millarc64edde2009-04-18 12:26:32 -07004374 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004375
4376 /**
4377 * How long (in ms) this uid has been keeping the device fully awake.
4378 */
Evan Millarc64edde2009-04-18 12:26:32 -07004379 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380
4381 /**
4382 * How long (in ms) this uid has had a window keeping the device awake.
4383 */
Evan Millarc64edde2009-04-18 12:26:32 -07004384 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385
4386 /**
4387 * Reads a possibly null Timer from a Parcel. The timer is associated with the
4388 * proper timer pool from the given BatteryStatsImpl object.
4389 *
4390 * @param in the Parcel to be read from.
4391 * return a new Timer, or null.
4392 */
Evan Millarc64edde2009-04-18 12:26:32 -07004393 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004394 TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004395 if (in.readInt() == 0) {
4396 return null;
4397 }
4398
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004399 return new StopwatchTimer(Uid.this, type, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004400 }
4401
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004402 boolean reset() {
4403 boolean wlactive = false;
4404 if (mTimerFull != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004405 wlactive |= !mTimerFull.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004406 }
4407 if (mTimerPartial != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004408 wlactive |= !mTimerPartial.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004409 }
4410 if (mTimerWindow != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004411 wlactive |= !mTimerWindow.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004412 }
4413 if (!wlactive) {
4414 if (mTimerFull != null) {
4415 mTimerFull.detach();
4416 mTimerFull = null;
4417 }
4418 if (mTimerPartial != null) {
4419 mTimerPartial.detach();
4420 mTimerPartial = null;
4421 }
4422 if (mTimerWindow != null) {
4423 mTimerWindow.detach();
4424 mTimerWindow = null;
4425 }
4426 }
4427 return !wlactive;
4428 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004429
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004430 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004431 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004432 mPartialTimers, screenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004434 mFullTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004435 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004436 mWindowTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 }
4438
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004439 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
4440 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
4441 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
4442 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004443 }
4444
4445 @Override
4446 public Timer getWakeTime(int type) {
4447 switch (type) {
4448 case WAKE_TYPE_FULL: return mTimerFull;
4449 case WAKE_TYPE_PARTIAL: return mTimerPartial;
4450 case WAKE_TYPE_WINDOW: return mTimerWindow;
4451 default: throw new IllegalArgumentException("type = " + type);
4452 }
4453 }
4454 }
4455
4456 public final class Sensor extends BatteryStats.Uid.Sensor {
4457 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07004458 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 public Sensor(int handle) {
4461 mHandle = handle;
4462 }
4463
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004464 private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 if (in.readInt() == 0) {
4466 return null;
4467 }
4468
Evan Millarc64edde2009-04-18 12:26:32 -07004469 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004470 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07004471 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 mSensorTimers.put(mHandle, pool);
4473 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004474 return new StopwatchTimer(Uid.this, 0, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475 }
4476
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004477 boolean reset() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004478 if (mTimer.reset(true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004479 mTimer = null;
4480 return true;
4481 }
4482 return false;
4483 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004484
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004485 void readFromParcelLocked(TimeBase timeBase, Parcel in) {
4486 mTimer = readTimerFromParcel(timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004487 }
4488
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004489 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
4490 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 }
4492
4493 @Override
4494 public Timer getSensorTime() {
4495 return mTimer;
4496 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004497
4498 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004499 public int getHandle() {
4500 return mHandle;
4501 }
4502 }
4503
4504 /**
4505 * The statistics associated with a particular process.
4506 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004507 public final class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -08004509 * Remains true until removed from the stats.
4510 */
4511 boolean mActive = true;
4512
4513 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 * Total time (in 1/100 sec) spent executing in user code.
4515 */
4516 long mUserTime;
4517
4518 /**
4519 * Total time (in 1/100 sec) spent executing in kernel code.
4520 */
4521 long mSystemTime;
4522
4523 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004524 * Amount of time the process was running in the foreground.
4525 */
4526 long mForegroundTime;
4527
4528 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004529 * Number of times the process has been started.
4530 */
4531 int mStarts;
4532
4533 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004534 * The amount of user time loaded from a previous save.
4535 */
4536 long mLoadedUserTime;
4537
4538 /**
4539 * The amount of system time loaded from a previous save.
4540 */
4541 long mLoadedSystemTime;
4542
4543 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004544 * The amount of foreground time loaded from a previous save.
4545 */
4546 long mLoadedForegroundTime;
4547
4548 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004549 * The number of times the process has started from a previous save.
4550 */
4551 int mLoadedStarts;
4552
4553 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004554 * The amount of user time loaded from the previous run.
4555 */
4556 long mLastUserTime;
4557
4558 /**
4559 * The amount of system time loaded from the previous run.
4560 */
4561 long mLastSystemTime;
4562
4563 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004564 * The amount of foreground time loaded from the previous run
4565 */
4566 long mLastForegroundTime;
4567
4568 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004569 * The number of times the process has started from the previous run.
4570 */
4571 int mLastStarts;
4572
4573 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004574 * The amount of user time when last unplugged.
4575 */
4576 long mUnpluggedUserTime;
4577
4578 /**
4579 * The amount of system time when last unplugged.
4580 */
4581 long mUnpluggedSystemTime;
4582
4583 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004584 * The amount of foreground time since unplugged.
4585 */
4586 long mUnpluggedForegroundTime;
4587
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004588 /**
4589 * The number of times the process has started before unplugged.
4590 */
4591 int mUnpluggedStarts;
4592
Amith Yamasanie43530a2009-08-21 13:11:37 -07004593 SamplingCounter[] mSpeedBins;
4594
Dianne Hackborn287952c2010-09-22 22:34:31 -07004595 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004597 Proc() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004598 mOnBatteryTimeBase.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07004599 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004601
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004602 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 mUnpluggedUserTime = mUserTime;
4604 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004605 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004606 mUnpluggedStarts = mStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004607 }
4608
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004609 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004610 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004611
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004612 void detach() {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004613 mActive = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004614 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004615 for (int i = 0; i < mSpeedBins.length; i++) {
4616 SamplingCounter c = mSpeedBins[i];
4617 if (c != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004618 mOnBatteryTimeBase.remove(c);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004619 mSpeedBins[i] = null;
4620 }
4621 }
4622 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004623
Dianne Hackborn287952c2010-09-22 22:34:31 -07004624 public int countExcessivePowers() {
4625 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004626 }
4627
Dianne Hackborn287952c2010-09-22 22:34:31 -07004628 public ExcessivePower getExcessivePower(int i) {
4629 if (mExcessivePower != null) {
4630 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004631 }
4632 return null;
4633 }
4634
4635 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004636 if (mExcessivePower == null) {
4637 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004638 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07004639 ExcessivePower ew = new ExcessivePower();
4640 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004641 ew.overTime = overTime;
4642 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07004643 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004644 }
4645
Dianne Hackborn287952c2010-09-22 22:34:31 -07004646 public void addExcessiveCpu(long overTime, long usedTime) {
4647 if (mExcessivePower == null) {
4648 mExcessivePower = new ArrayList<ExcessivePower>();
4649 }
4650 ExcessivePower ew = new ExcessivePower();
4651 ew.type = ExcessivePower.TYPE_CPU;
4652 ew.overTime = overTime;
4653 ew.usedTime = usedTime;
4654 mExcessivePower.add(ew);
4655 }
4656
4657 void writeExcessivePowerToParcelLocked(Parcel out) {
4658 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004659 out.writeInt(0);
4660 return;
4661 }
4662
Dianne Hackborn287952c2010-09-22 22:34:31 -07004663 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004664 out.writeInt(N);
4665 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004666 ExcessivePower ew = mExcessivePower.get(i);
4667 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004668 out.writeLong(ew.overTime);
4669 out.writeLong(ew.usedTime);
4670 }
4671 }
4672
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004673 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004674 final int N = in.readInt();
4675 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004676 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004677 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004678 }
4679
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004680 if (N > 10000) {
4681 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
4682 return false;
4683 }
4684
Dianne Hackborn287952c2010-09-22 22:34:31 -07004685 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004686 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004687 ExcessivePower ew = new ExcessivePower();
4688 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004689 ew.overTime = in.readLong();
4690 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07004691 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004692 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004693 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004694 }
4695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004696 void writeToParcelLocked(Parcel out) {
4697 out.writeLong(mUserTime);
4698 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004699 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004700 out.writeInt(mStarts);
4701 out.writeLong(mLoadedUserTime);
4702 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004703 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004704 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705 out.writeLong(mUnpluggedUserTime);
4706 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004707 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004708 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07004709
4710 out.writeInt(mSpeedBins.length);
4711 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004712 SamplingCounter c = mSpeedBins[i];
4713 if (c != null) {
4714 out.writeInt(1);
4715 c.writeToParcel(out);
4716 } else {
4717 out.writeInt(0);
4718 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004719 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004720
Dianne Hackborn287952c2010-09-22 22:34:31 -07004721 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004722 }
4723
4724 void readFromParcelLocked(Parcel in) {
4725 mUserTime = in.readLong();
4726 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004727 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004728 mStarts = in.readInt();
4729 mLoadedUserTime = in.readLong();
4730 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004731 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004732 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004733 mLastUserTime = 0;
4734 mLastSystemTime = 0;
4735 mLastForegroundTime = 0;
4736 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004737 mUnpluggedUserTime = in.readLong();
4738 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004739 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07004741
4742 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004743 int steps = getCpuSpeedSteps();
4744 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07004745 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004746 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004747 mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004748 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004749 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004750
Dianne Hackborn287952c2010-09-22 22:34:31 -07004751 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004752 }
4753
4754 public BatteryStatsImpl getBatteryStats() {
4755 return BatteryStatsImpl.this;
4756 }
4757
4758 public void addCpuTimeLocked(int utime, int stime) {
4759 mUserTime += utime;
4760 mSystemTime += stime;
4761 }
4762
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004763 public void addForegroundTimeLocked(long ttime) {
4764 mForegroundTime += ttime;
4765 }
4766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004767 public void incStartsLocked() {
4768 mStarts++;
4769 }
4770
4771 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08004772 public boolean isActive() {
4773 return mActive;
4774 }
4775
4776 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004777 public long getUserTime(int which) {
4778 long val;
4779 if (which == STATS_LAST) {
4780 val = mLastUserTime;
4781 } else {
4782 val = mUserTime;
4783 if (which == STATS_CURRENT) {
4784 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004785 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004786 val -= mUnpluggedUserTime;
4787 }
4788 }
4789 return val;
4790 }
4791
4792 @Override
4793 public long getSystemTime(int which) {
4794 long val;
4795 if (which == STATS_LAST) {
4796 val = mLastSystemTime;
4797 } else {
4798 val = mSystemTime;
4799 if (which == STATS_CURRENT) {
4800 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004801 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 val -= mUnpluggedSystemTime;
4803 }
4804 }
4805 return val;
4806 }
4807
4808 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004809 public long getForegroundTime(int which) {
4810 long val;
4811 if (which == STATS_LAST) {
4812 val = mLastForegroundTime;
4813 } else {
4814 val = mForegroundTime;
4815 if (which == STATS_CURRENT) {
4816 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004817 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004818 val -= mUnpluggedForegroundTime;
4819 }
4820 }
4821 return val;
4822 }
4823
4824 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004825 public int getStarts(int which) {
4826 int val;
4827 if (which == STATS_LAST) {
4828 val = mLastStarts;
4829 } else {
4830 val = mStarts;
4831 if (which == STATS_CURRENT) {
4832 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004833 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834 val -= mUnpluggedStarts;
4835 }
4836 }
4837 return val;
4838 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004839
4840 /* Called by ActivityManagerService when CPU times are updated. */
4841 public void addSpeedStepTimes(long[] values) {
4842 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004843 long amt = values[i];
4844 if (amt != 0) {
4845 SamplingCounter c = mSpeedBins[i];
4846 if (c == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004847 mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004848 }
4849 c.addCountAtomic(values[i]);
4850 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004851 }
4852 }
4853
4854 @Override
4855 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
4856 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004857 SamplingCounter c = mSpeedBins[speedStep];
4858 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07004859 } else {
4860 return 0;
4861 }
4862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004863 }
4864
4865 /**
4866 * The statistics associated with a particular package.
4867 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004868 public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004869 /**
4870 * Number of times this package has done something that could wake up the
4871 * device from sleep.
4872 */
4873 int mWakeups;
4874
4875 /**
4876 * Number of things that could wake up the device loaded from a
4877 * previous save.
4878 */
4879 int mLoadedWakeups;
4880
4881 /**
4882 * Number of things that could wake up the device as of the
4883 * last run.
4884 */
4885 int mLastWakeups;
4886
4887 /**
4888 * Number of things that could wake up the device as of the
4889 * last run.
4890 */
4891 int mUnpluggedWakeups;
4892
4893 /**
4894 * The statics we have collected for this package's services.
4895 */
4896 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
4897
4898 Pkg() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004899 mOnBatteryScreenOffTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004901
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004902 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004903 mUnpluggedWakeups = mWakeups;
4904 }
4905
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004906 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004907 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004908
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004909 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004910 mOnBatteryScreenOffTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004911 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004913 void readFromParcelLocked(Parcel in) {
4914 mWakeups = in.readInt();
4915 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004916 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004917 mUnpluggedWakeups = in.readInt();
4918
4919 int numServs = in.readInt();
4920 mServiceStats.clear();
4921 for (int m = 0; m < numServs; m++) {
4922 String serviceName = in.readString();
4923 Uid.Pkg.Serv serv = new Serv();
4924 mServiceStats.put(serviceName, serv);
4925
4926 serv.readFromParcelLocked(in);
4927 }
4928 }
4929
4930 void writeToParcelLocked(Parcel out) {
4931 out.writeInt(mWakeups);
4932 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 out.writeInt(mUnpluggedWakeups);
4934
4935 out.writeInt(mServiceStats.size());
4936 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
4937 out.writeString(servEntry.getKey());
4938 Uid.Pkg.Serv serv = servEntry.getValue();
4939
4940 serv.writeToParcelLocked(out);
4941 }
4942 }
4943
4944 @Override
4945 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
4946 return mServiceStats;
4947 }
4948
4949 @Override
4950 public int getWakeups(int which) {
4951 int val;
4952 if (which == STATS_LAST) {
4953 val = mLastWakeups;
4954 } else {
4955 val = mWakeups;
4956 if (which == STATS_CURRENT) {
4957 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004958 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004959 val -= mUnpluggedWakeups;
4960 }
4961 }
4962
4963 return val;
4964 }
4965
4966 /**
4967 * The statistics associated with a particular service.
4968 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004969 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004970 /**
4971 * Total time (ms in battery uptime) the service has been left started.
4972 */
4973 long mStartTime;
4974
4975 /**
4976 * If service has been started and not yet stopped, this is
4977 * when it was started.
4978 */
4979 long mRunningSince;
4980
4981 /**
4982 * True if we are currently running.
4983 */
4984 boolean mRunning;
4985
4986 /**
4987 * Total number of times startService() has been called.
4988 */
4989 int mStarts;
4990
4991 /**
4992 * Total time (ms in battery uptime) the service has been left launched.
4993 */
4994 long mLaunchedTime;
4995
4996 /**
4997 * If service has been launched and not yet exited, this is
4998 * when it was launched (ms in battery uptime).
4999 */
5000 long mLaunchedSince;
5001
5002 /**
5003 * True if we are currently launched.
5004 */
5005 boolean mLaunched;
5006
5007 /**
5008 * Total number times the service has been launched.
5009 */
5010 int mLaunches;
5011
5012 /**
5013 * The amount of time spent started loaded from a previous save
5014 * (ms in battery uptime).
5015 */
5016 long mLoadedStartTime;
5017
5018 /**
5019 * The number of starts loaded from a previous save.
5020 */
5021 int mLoadedStarts;
5022
5023 /**
5024 * The number of launches loaded from a previous save.
5025 */
5026 int mLoadedLaunches;
5027
5028 /**
5029 * The amount of time spent started as of the last run (ms
5030 * in battery uptime).
5031 */
5032 long mLastStartTime;
5033
5034 /**
5035 * The number of starts as of the last run.
5036 */
5037 int mLastStarts;
5038
5039 /**
5040 * The number of launches as of the last run.
5041 */
5042 int mLastLaunches;
5043
5044 /**
5045 * The amount of time spent started when last unplugged (ms
5046 * in battery uptime).
5047 */
5048 long mUnpluggedStartTime;
5049
5050 /**
5051 * The number of starts when last unplugged.
5052 */
5053 int mUnpluggedStarts;
5054
5055 /**
5056 * The number of launches when last unplugged.
5057 */
5058 int mUnpluggedLaunches;
5059
5060 Serv() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005061 mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005062 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005063
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005064 public void onTimeStarted(long elapsedRealtime, long baseUptime,
5065 long baseRealtime) {
5066 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005067 mUnpluggedStarts = mStarts;
5068 mUnpluggedLaunches = mLaunches;
5069 }
5070
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005071 public void onTimeStopped(long elapsedRealtime, long baseUptime,
5072 long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005073 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005074
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005075 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005076 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005077 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005079 void readFromParcelLocked(Parcel in) {
5080 mStartTime = in.readLong();
5081 mRunningSince = in.readLong();
5082 mRunning = in.readInt() != 0;
5083 mStarts = in.readInt();
5084 mLaunchedTime = in.readLong();
5085 mLaunchedSince = in.readLong();
5086 mLaunched = in.readInt() != 0;
5087 mLaunches = in.readInt();
5088 mLoadedStartTime = in.readLong();
5089 mLoadedStarts = in.readInt();
5090 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005091 mLastStartTime = 0;
5092 mLastStarts = 0;
5093 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005094 mUnpluggedStartTime = in.readLong();
5095 mUnpluggedStarts = in.readInt();
5096 mUnpluggedLaunches = in.readInt();
5097 }
5098
5099 void writeToParcelLocked(Parcel out) {
5100 out.writeLong(mStartTime);
5101 out.writeLong(mRunningSince);
5102 out.writeInt(mRunning ? 1 : 0);
5103 out.writeInt(mStarts);
5104 out.writeLong(mLaunchedTime);
5105 out.writeLong(mLaunchedSince);
5106 out.writeInt(mLaunched ? 1 : 0);
5107 out.writeInt(mLaunches);
5108 out.writeLong(mLoadedStartTime);
5109 out.writeInt(mLoadedStarts);
5110 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005111 out.writeLong(mUnpluggedStartTime);
5112 out.writeInt(mUnpluggedStarts);
5113 out.writeInt(mUnpluggedLaunches);
5114 }
5115
5116 long getLaunchTimeToNowLocked(long batteryUptime) {
5117 if (!mLaunched) return mLaunchedTime;
5118 return mLaunchedTime + batteryUptime - mLaunchedSince;
5119 }
5120
5121 long getStartTimeToNowLocked(long batteryUptime) {
5122 if (!mRunning) return mStartTime;
5123 return mStartTime + batteryUptime - mRunningSince;
5124 }
5125
5126 public void startLaunchedLocked() {
5127 if (!mLaunched) {
5128 mLaunches++;
5129 mLaunchedSince = getBatteryUptimeLocked();
5130 mLaunched = true;
5131 }
5132 }
5133
5134 public void stopLaunchedLocked() {
5135 if (mLaunched) {
5136 long time = getBatteryUptimeLocked() - mLaunchedSince;
5137 if (time > 0) {
5138 mLaunchedTime += time;
5139 } else {
5140 mLaunches--;
5141 }
5142 mLaunched = false;
5143 }
5144 }
5145
5146 public void startRunningLocked() {
5147 if (!mRunning) {
5148 mStarts++;
5149 mRunningSince = getBatteryUptimeLocked();
5150 mRunning = true;
5151 }
5152 }
5153
5154 public void stopRunningLocked() {
5155 if (mRunning) {
5156 long time = getBatteryUptimeLocked() - mRunningSince;
5157 if (time > 0) {
5158 mStartTime += time;
5159 } else {
5160 mStarts--;
5161 }
5162 mRunning = false;
5163 }
5164 }
5165
5166 public BatteryStatsImpl getBatteryStats() {
5167 return BatteryStatsImpl.this;
5168 }
5169
5170 @Override
5171 public int getLaunches(int which) {
5172 int val;
5173
5174 if (which == STATS_LAST) {
5175 val = mLastLaunches;
5176 } else {
5177 val = mLaunches;
5178 if (which == STATS_CURRENT) {
5179 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005180 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 val -= mUnpluggedLaunches;
5182 }
5183 }
5184
5185 return val;
5186 }
5187
5188 @Override
5189 public long getStartTime(long now, int which) {
5190 long val;
5191 if (which == STATS_LAST) {
5192 val = mLastStartTime;
5193 } else {
5194 val = getStartTimeToNowLocked(now);
5195 if (which == STATS_CURRENT) {
5196 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005197 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005198 val -= mUnpluggedStartTime;
5199 }
5200 }
5201
5202 return val;
5203 }
5204
5205 @Override
5206 public int getStarts(int which) {
5207 int val;
5208 if (which == STATS_LAST) {
5209 val = mLastStarts;
5210 } else {
5211 val = mStarts;
5212 if (which == STATS_CURRENT) {
5213 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005214 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005215 val -= mUnpluggedStarts;
5216 }
5217 }
5218
5219 return val;
5220 }
5221 }
5222
5223 public BatteryStatsImpl getBatteryStats() {
5224 return BatteryStatsImpl.this;
5225 }
5226
5227 public void incWakeupsLocked() {
5228 mWakeups++;
5229 }
5230
5231 final Serv newServiceStatsLocked() {
5232 return new Serv();
5233 }
5234 }
5235
5236 /**
5237 * Retrieve the statistics object for a particular process, creating
5238 * if needed.
5239 */
5240 public Proc getProcessStatsLocked(String name) {
5241 Proc ps = mProcessStats.get(name);
5242 if (ps == null) {
5243 ps = new Proc();
5244 mProcessStats.put(name, ps);
5245 }
5246
5247 return ps;
5248 }
5249
Dianne Hackbornb5e31652010-09-07 12:13:55 -07005250 public SparseArray<? extends Pid> getPidStats() {
5251 return mPids;
5252 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005253
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005254 public Pid getPidStatsLocked(int pid) {
5255 Pid p = mPids.get(pid);
5256 if (p == null) {
5257 p = new Pid();
5258 mPids.put(pid, p);
5259 }
5260 return p;
5261 }
5262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005263 /**
5264 * Retrieve the statistics object for a particular service, creating
5265 * if needed.
5266 */
5267 public Pkg getPackageStatsLocked(String name) {
5268 Pkg ps = mPackageStats.get(name);
5269 if (ps == null) {
5270 ps = new Pkg();
5271 mPackageStats.put(name, ps);
5272 }
5273
5274 return ps;
5275 }
5276
5277 /**
5278 * Retrieve the statistics object for a particular service, creating
5279 * if needed.
5280 */
5281 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
5282 Pkg ps = getPackageStatsLocked(pkg);
5283 Pkg.Serv ss = ps.mServiceStats.get(serv);
5284 if (ss == null) {
5285 ss = ps.newServiceStatsLocked();
5286 ps.mServiceStats.put(serv, ss);
5287 }
5288
5289 return ss;
5290 }
5291
Evan Millarc64edde2009-04-18 12:26:32 -07005292 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005293 Wakelock wl = mWakelockStats.get(name);
5294 if (wl == null) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07005295 final int N = mWakelockStats.size();
Dianne Hackbornaf17baa2013-05-09 15:27:47 -07005296 if (N > MAX_WAKELOCKS_PER_UID) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005297 name = BATCHED_WAKELOCK_NAME;
5298 wl = mWakelockStats.get(name);
5299 }
5300 if (wl == null) {
5301 wl = new Wakelock();
5302 mWakelockStats.put(name, wl);
5303 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005304 }
Evan Millarc64edde2009-04-18 12:26:32 -07005305 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005306 switch (type) {
5307 case WAKE_TYPE_PARTIAL:
5308 t = wl.mTimerPartial;
5309 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005310 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005311 mPartialTimers, mOnBatteryScreenOffTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005312 wl.mTimerPartial = t;
5313 }
5314 return t;
5315 case WAKE_TYPE_FULL:
5316 t = wl.mTimerFull;
5317 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005318 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005319 mFullTimers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005320 wl.mTimerFull = t;
5321 }
5322 return t;
5323 case WAKE_TYPE_WINDOW:
5324 t = wl.mTimerWindow;
5325 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005326 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005327 mWindowTimers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005328 wl.mTimerWindow = t;
5329 }
5330 return t;
5331 default:
5332 throw new IllegalArgumentException("type=" + type);
5333 }
5334 }
5335
Evan Millarc64edde2009-04-18 12:26:32 -07005336 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337 Sensor se = mSensorStats.get(sensor);
5338 if (se == null) {
5339 if (!create) {
5340 return null;
5341 }
5342 se = new Sensor(sensor);
5343 mSensorStats.put(sensor, se);
5344 }
Evan Millarc64edde2009-04-18 12:26:32 -07005345 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005346 if (t != null) {
5347 return t;
5348 }
Evan Millarc64edde2009-04-18 12:26:32 -07005349 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005350 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07005351 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005352 mSensorTimers.put(sensor, timers);
5353 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005354 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005355 se.mTimer = t;
5356 return t;
5357 }
5358
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005359 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005360 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005361 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005362 t.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005363 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07005364 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005365 Pid p = getPidStatsLocked(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005366 if (p.mWakeNesting++ == 0) {
5367 p.mWakeStartMs = elapsedRealtimeMs;
Dianne Hackbornb8071d792010-09-09 16:45:15 -07005368 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005369 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005370 }
5371
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005372 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005373 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005374 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005375 t.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07005377 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005378 Pid p = mPids.get(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005379 if (p != null && p.mWakeNesting > 0) {
5380 if (p.mWakeNesting-- == 1) {
5381 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
5382 p.mWakeStartMs = 0;
5383 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005384 }
5385 }
5386 }
5387
5388 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
5389 Proc p = getProcessStatsLocked(proc);
5390 if (p != null) {
5391 p.addExcessiveWake(overTime, usedTime);
5392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005393 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005394
Dianne Hackborn287952c2010-09-22 22:34:31 -07005395 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
5396 Proc p = getProcessStatsLocked(proc);
5397 if (p != null) {
5398 p.addExcessiveCpu(overTime, usedTime);
5399 }
5400 }
5401
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005402 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005403 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005404 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005405 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 }
5408
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005409 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07005411 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005412 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005413 t.stopRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005414 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005415 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005416
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005417 public void noteStartGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005418 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005419 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005420 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005421 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005422 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005423
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005424 public void noteStopGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005425 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005426 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005427 t.stopRunningLocked(elapsedRealtimeMs);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005428 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005429 }
5430
5431 public BatteryStatsImpl getBatteryStats() {
5432 return BatteryStatsImpl.this;
5433 }
5434 }
5435
Jeff Brown6f357d32014-01-15 20:40:55 -08005436 public BatteryStatsImpl(String filename, Handler handler) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005437 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Jeff Brown6f357d32014-01-15 20:40:55 -08005438 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005439 mStartCount++;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005440 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005441 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005442 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005443 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005444 mInputEventCounter = new Counter(mOnBatteryTimeBase);
5445 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase);
Wink Saville52840902011-02-18 12:40:47 -08005446 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005447 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null,
5448 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005449 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005450 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005451 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005452 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null,
5453 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005454 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005455 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005456 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
5457 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005458 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005459 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase);
5460 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase);
5461 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
5462 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
5463 mWifiOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase);
5464 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005465 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005466 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005467 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005468 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005469 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005470 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, null, mOnBatteryTimeBase);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08005471 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005472 mAudioOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase);
5473 mVideoOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005474 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005475 long uptime = SystemClock.uptimeMillis() * 1000;
5476 long realtime = SystemClock.elapsedRealtime() * 1000;
5477 initTimes(uptime, realtime);
5478 mUptimeStart = uptime;
5479 mRealtimeStart = realtime;
Evan Millar633a1742009-04-02 16:36:33 -07005480 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005481 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07005482 mDischargeCurrentLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005483 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005484 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005485 }
5486
5487 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005488 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005489 mHandler = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005490 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005491 readFromParcel(p);
5492 }
5493
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005494 public void setCallback(BatteryCallback cb) {
5495 mCallback = cb;
5496 }
5497
Amith Yamasanie43530a2009-08-21 13:11:37 -07005498 public void setNumSpeedSteps(int steps) {
5499 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
5500 }
5501
Amith Yamasanif37447b2009-10-08 18:28:01 -07005502 public void setRadioScanningTimeout(long timeout) {
5503 if (mPhoneSignalScanningTimer != null) {
5504 mPhoneSignalScanningTimer.setTimeout(timeout);
5505 }
5506 }
5507
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005508 @Override
5509 public boolean startIteratingOldHistoryLocked() {
5510 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
5511 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005512 if ((mHistoryIterator = mHistory) == null) {
5513 return false;
5514 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005515 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005516 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005517 mReadOverflow = false;
5518 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005519 return true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005520 }
5521
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005522 @Override
5523 public boolean getNextOldHistoryLocked(HistoryItem out) {
5524 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
5525 if (!end) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005526 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005527 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005528 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005529 HistoryItem cur = mHistoryIterator;
5530 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005531 if (!mReadOverflow && !end) {
5532 Slog.w(TAG, "Old history ends before new history!");
5533 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005534 return false;
5535 }
5536 out.setTo(cur);
5537 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005538 if (!mReadOverflow) {
5539 if (end) {
5540 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005541 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005542 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
Dianne Hackborn8c841092013-06-24 13:46:13 -07005543 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005544 pw.println("Histories differ!");
5545 pw.println("Old history:");
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005546 (new HistoryPrinter()).printNextItem(pw, out, now, false);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005547 pw.println("New history:");
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005548 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now, false);
Dianne Hackborn8c841092013-06-24 13:46:13 -07005549 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005550 }
5551 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005552 return true;
5553 }
5554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005555 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005556 public void finishIteratingOldHistoryLocked() {
5557 mIteratingHistory = false;
5558 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005559 mHistoryIterator = null;
5560 }
5561
5562 public int getHistoryTotalSize() {
5563 return MAX_HISTORY_BUFFER;
5564 }
5565
5566 public int getHistoryUsedSize() {
5567 return mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005568 }
5569
5570 @Override
5571 public boolean startIteratingHistoryLocked() {
5572 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
5573 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005574 if (mHistoryBuffer.dataSize() <= 0) {
5575 return false;
5576 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005577 mHistoryBuffer.setDataPosition(0);
5578 mReadOverflow = false;
5579 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005580 mReadHistoryStrings = new String[mHistoryTagPool.size()];
5581 mReadHistoryUids = new int[mHistoryTagPool.size()];
5582 mReadHistoryChars = 0;
5583 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
5584 final HistoryTag tag = ent.getKey();
5585 final int idx = ent.getValue();
5586 mReadHistoryStrings[idx] = tag.string;
5587 mReadHistoryUids[idx] = tag.uid;
5588 mReadHistoryChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08005589 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005590 return true;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005591 }
5592
5593 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08005594 public int getHistoryStringPoolSize() {
5595 return mReadHistoryStrings.length;
5596 }
5597
5598 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005599 public int getHistoryStringPoolBytes() {
5600 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
5601 // Each string character is 2 bytes.
5602 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
5603 }
5604
5605 @Override
5606 public String getHistoryTagPoolString(int index) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005607 return mReadHistoryStrings[index];
5608 }
5609
5610 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005611 public int getHistoryTagPoolUid(int index) {
5612 return mReadHistoryUids[index];
5613 }
5614
5615 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005616 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005617 final int pos = mHistoryBuffer.dataPosition();
5618 if (pos == 0) {
5619 out.clear();
5620 }
5621 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005622 if (end) {
5623 return false;
5624 }
5625
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005626 readHistoryDelta(mHistoryBuffer, out);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005627 return true;
5628 }
5629
5630 @Override
5631 public void finishIteratingHistoryLocked() {
5632 mIteratingHistory = false;
5633 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn099bc622014-01-22 13:39:16 -08005634 mReadHistoryStrings = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005635 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005636
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005637 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07005638 public long getHistoryBaseTime() {
5639 return mHistoryBaseTime;
5640 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005641
Dianne Hackbornb5e31652010-09-07 12:13:55 -07005642 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 public int getStartCount() {
5644 return mStartCount;
5645 }
5646
5647 public boolean isOnBattery() {
5648 return mOnBattery;
5649 }
5650
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005651 public boolean isScreenOn() {
5652 return mScreenOn;
5653 }
5654
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005655 void initTimes(long uptime, long realtime) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08005656 mStartClockTime = System.currentTimeMillis();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005657 mOnBatteryTimeBase.init(uptime, realtime);
5658 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
5659 mUptimeStart = uptime;
5660 mRealtimeStart = realtime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005661 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005662
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005663 void initDischarge() {
5664 mLowDischargeAmountSinceCharge = 0;
5665 mHighDischargeAmountSinceCharge = 0;
5666 mDischargeAmountScreenOn = 0;
5667 mDischargeAmountScreenOnSinceCharge = 0;
5668 mDischargeAmountScreenOff = 0;
5669 mDischargeAmountScreenOffSinceCharge = 0;
5670 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005671
5672 public void resetAllStatsCmdLocked() {
5673 resetAllStatsLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07005674 final long mSecUptime = SystemClock.uptimeMillis();
5675 long uptime = mSecUptime * 1000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005676 long mSecRealtime = SystemClock.elapsedRealtime();
5677 long realtime = mSecRealtime * 1000;
5678 mDischargeStartLevel = mHistoryCur.batteryLevel;
5679 pullPendingStateUpdatesLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07005680 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005681 mDischargeCurrentLevel = mDischargeUnplugLevel = mHistoryCur.batteryLevel;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005682 mOnBatteryTimeBase.reset(uptime, realtime);
5683 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
5684 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005685 if (mScreenOn) {
5686 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
5687 mDischargeScreenOffUnplugLevel = 0;
5688 } else {
5689 mDischargeScreenOnUnplugLevel = 0;
5690 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
5691 }
5692 mDischargeAmountScreenOn = 0;
5693 mDischargeAmountScreenOff = 0;
5694 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07005695 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005696 }
5697
5698 private void resetAllStatsLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005699 mStartCount = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005700 initTimes(SystemClock.uptimeMillis() * 1000, SystemClock.elapsedRealtime() * 1000);
5701 mScreenOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005702 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005703 mScreenBrightnessTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005704 }
5705 mInputEventCounter.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005706 mPhoneOnTimer.reset(false);
5707 mAudioOnTimer.reset(false);
5708 mVideoOnTimer.reset(false);
Wink Saville52840902011-02-18 12:40:47 -08005709 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005710 mPhoneSignalStrengthsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005711 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005712 mPhoneSignalScanningTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005713 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005714 mPhoneDataConnectionsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005715 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005716 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005717 mNetworkByteActivityCounters[i].reset(false);
5718 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005719 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005720 mMobileRadioActiveTimer.reset(false);
5721 mMobileRadioActivePerAppTimer.reset(false);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005722 mMobileRadioActiveUnknownTime.reset(false);
5723 mMobileRadioActiveUnknownCount.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005724 mWifiOnTimer.reset(false);
5725 mGlobalWifiRunningTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005726 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005727 mWifiStateTimer[i].reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005728 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005729 mBluetoothOnTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005730 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005731 mBluetoothStateTimer[i].reset(false);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08005732 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005733
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005734 for (int i=0; i<mUidStats.size(); i++) {
5735 if (mUidStats.valueAt(i).reset()) {
5736 mUidStats.remove(mUidStats.keyAt(i));
5737 i--;
5738 }
5739 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005740
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005741 if (mKernelWakelockStats.size() > 0) {
5742 for (SamplingTimer timer : mKernelWakelockStats.values()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005743 mOnBatteryScreenOffTimeBase.remove(timer);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005744 }
5745 mKernelWakelockStats.clear();
5746 }
5747
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005748 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005749
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005750 clearHistoryLocked();
5751 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005752
Dianne Hackborn40c87252014-03-19 16:55:40 -07005753 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005754 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
5755 HashMap<String, SparseBooleanArray> active = mActiveEvents[i];
5756 if (active == null) {
5757 continue;
5758 }
5759 for (HashMap.Entry<String, SparseBooleanArray> ent : active.entrySet()) {
5760 SparseBooleanArray uids = ent.getValue();
5761 for (int j=0; j<uids.size(); j++) {
5762 if (uids.valueAt(j)) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07005763 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
5764 uids.keyAt(j));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005765 }
5766 }
5767 }
5768 }
5769 }
5770
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005771 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005772 if (oldScreenOn) {
5773 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
5774 if (diff > 0) {
5775 mDischargeAmountScreenOn += diff;
5776 mDischargeAmountScreenOnSinceCharge += diff;
5777 }
5778 } else {
5779 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
5780 if (diff > 0) {
5781 mDischargeAmountScreenOff += diff;
5782 mDischargeAmountScreenOffSinceCharge += diff;
5783 }
5784 }
5785 if (newScreenOn) {
5786 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
5787 mDischargeScreenOffUnplugLevel = 0;
5788 } else {
5789 mDischargeScreenOnUnplugLevel = 0;
5790 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
5791 }
5792 }
5793
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005794 public void pullPendingStateUpdatesLocked() {
5795 updateKernelWakelocksLocked();
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005796 updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
Dianne Hackborn77b987f2014-02-26 16:20:52 -08005797 if (mOnBatteryInternal) {
5798 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
5799 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005800 }
5801
Dianne Hackborn40c87252014-03-19 16:55:40 -07005802 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
5803 final int oldStatus, final int level) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005804 boolean doWrite = false;
5805 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
5806 m.arg1 = onBattery ? 1 : 0;
5807 mHandler.sendMessage(m);
5808 mOnBattery = mOnBatteryInternal = onBattery;
5809
Dianne Hackborn40c87252014-03-19 16:55:40 -07005810 final long uptime = mSecUptime * 1000;
5811 final long realtime = mSecRealtime * 1000;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005812 if (onBattery) {
5813 // We will reset our status if we are unplugging after the
5814 // battery was last full, or the level is at 100, or
5815 // we have gone through a significant charge (from a very low
5816 // level to a now very high level).
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005817 boolean reset = false;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005818 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
5819 || level >= 90
5820 || (mDischargeCurrentLevel < 20 && level >= 80)) {
5821 doWrite = true;
5822 resetAllStatsLocked();
5823 mDischargeStartLevel = level;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005824 reset = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005825 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005826 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005827 mHistoryCur.batteryLevel = (byte)level;
5828 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
5829 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
5830 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005831 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn40c87252014-03-19 16:55:40 -07005832 addHistoryBufferLocked(mSecRealtime, mSecUptime, HistoryItem.CMD_CURRENT_TIME);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005833 mHistoryCur.currentTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07005834 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005835 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
5836 if (mScreenOn) {
5837 mDischargeScreenOnUnplugLevel = level;
5838 mDischargeScreenOffUnplugLevel = 0;
5839 } else {
5840 mDischargeScreenOnUnplugLevel = 0;
5841 mDischargeScreenOffUnplugLevel = level;
5842 }
5843 mDischargeAmountScreenOn = 0;
5844 mDischargeAmountScreenOff = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005845 updateTimeBasesLocked(true, !mScreenOn, uptime, realtime);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005846 if (reset) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07005847 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005848 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005849 } else {
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005850 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005851 mHistoryCur.batteryLevel = (byte)level;
5852 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
5853 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
5854 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005855 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005856 mDischargeCurrentLevel = level;
5857 if (level < mDischargeUnplugLevel) {
5858 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
5859 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
5860 }
5861 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005862 updateTimeBasesLocked(false, !mScreenOn, uptime, realtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005863 }
5864 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
5865 if (mFile != null) {
5866 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005867 }
5868 }
5869 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005870
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005871 // This should probably be exposed in the API, though it's not critical
5872 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005873
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005874 public void setBatteryState(int status, int health, int plugType, int level,
5875 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005876 synchronized(this) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07005877 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
5878 final long uptime = SystemClock.uptimeMillis();
5879 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005880 int oldStatus = mHistoryCur.batteryStatus;
5881 if (!mHaveBatteryLevel) {
5882 mHaveBatteryLevel = true;
5883 // We start out assuming that the device is plugged in (not
5884 // on battery). If our first report is now that we are indeed
5885 // plugged in, then twiddle our state to correctly reflect that
5886 // since we won't be going through the full setOnBattery().
5887 if (onBattery == mOnBattery) {
5888 if (onBattery) {
5889 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
5890 } else {
5891 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
5892 }
5893 }
5894 oldStatus = status;
5895 }
5896 if (onBattery) {
5897 mDischargeCurrentLevel = level;
5898 mRecordingHistory = true;
5899 }
5900 if (onBattery != mOnBattery) {
5901 mHistoryCur.batteryLevel = (byte)level;
5902 mHistoryCur.batteryStatus = (byte)status;
5903 mHistoryCur.batteryHealth = (byte)health;
5904 mHistoryCur.batteryPlugType = (byte)plugType;
Sungmin Choic7e9e8b2013-01-16 12:57:36 +09005905 mHistoryCur.batteryTemperature = (short)temp;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005906 mHistoryCur.batteryVoltage = (char)volt;
Dianne Hackborn40c87252014-03-19 16:55:40 -07005907 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005908 } else {
5909 boolean changed = false;
5910 if (mHistoryCur.batteryLevel != level) {
5911 mHistoryCur.batteryLevel = (byte)level;
5912 changed = true;
5913 }
5914 if (mHistoryCur.batteryStatus != status) {
5915 mHistoryCur.batteryStatus = (byte)status;
5916 changed = true;
5917 }
5918 if (mHistoryCur.batteryHealth != health) {
5919 mHistoryCur.batteryHealth = (byte)health;
5920 changed = true;
5921 }
5922 if (mHistoryCur.batteryPlugType != plugType) {
5923 mHistoryCur.batteryPlugType = (byte)plugType;
5924 changed = true;
5925 }
5926 if (temp >= (mHistoryCur.batteryTemperature+10)
5927 || temp <= (mHistoryCur.batteryTemperature-10)) {
Sungmin Choic7e9e8b2013-01-16 12:57:36 +09005928 mHistoryCur.batteryTemperature = (short)temp;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005929 changed = true;
5930 }
5931 if (volt > (mHistoryCur.batteryVoltage+20)
5932 || volt < (mHistoryCur.batteryVoltage-20)) {
5933 mHistoryCur.batteryVoltage = (char)volt;
5934 changed = true;
5935 }
5936 if (changed) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07005937 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005938 }
5939 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005940 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
5941 // We don't record history while we are plugged in and fully charged.
5942 // The next time we are unplugged, history will be cleared.
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005943 mRecordingHistory = DEBUG;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005944 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005945 }
Evan Millar633a1742009-04-02 16:36:33 -07005946 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005947
Evan Millarc64edde2009-04-18 12:26:32 -07005948 public void updateKernelWakelocksLocked() {
5949 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005950
Marco Nelissend8593312009-04-30 14:45:06 -07005951 if (m == null) {
5952 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005953 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07005954 return;
5955 }
5956
Evan Millarc64edde2009-04-18 12:26:32 -07005957 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
5958 String name = ent.getKey();
5959 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005960
Evan Millarc64edde2009-04-18 12:26:32 -07005961 SamplingTimer kwlt = mKernelWakelockStats.get(name);
5962 if (kwlt == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005963 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
5964 true /* track reported val */);
Evan Millarc64edde2009-04-18 12:26:32 -07005965 mKernelWakelockStats.put(name, kwlt);
5966 }
5967 kwlt.updateCurrentReportedCount(kws.mCount);
5968 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
5969 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
5970 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005971
Evan Millarc64edde2009-04-18 12:26:32 -07005972 if (m.size() != mKernelWakelockStats.size()) {
5973 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
5974 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5975 SamplingTimer st = ent.getValue();
5976 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
5977 st.setStale();
5978 }
5979 }
5980 }
5981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005982
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005983 static final int NET_UPDATE_MOBILE = 1<<0;
5984 static final int NET_UPDATE_WIFI = 1<<1;
5985 static final int NET_UPDATE_ALL = 0xffff;
5986
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005987 private void updateNetworkActivityLocked(int which, long elapsedRealtimeMs) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005988 if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
5989
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005990 if ((which&NET_UPDATE_MOBILE) != 0 && mMobileIfaces.length > 0) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08005991 final NetworkStats snapshot;
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08005992 final NetworkStats last = mCurMobileSnapshot;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08005993 try {
5994 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
5995 mMobileIfaces, NetworkStats.TAG_NONE, mLastMobileSnapshot);
5996 } catch (IOException e) {
5997 Log.wtf(TAG, "Failed to read mobile network stats", e);
5998 return;
5999 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006000
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006001 mCurMobileSnapshot = snapshot;
6002 mLastMobileSnapshot = last;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006003
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006004 if (mOnBatteryInternal) {
6005 final NetworkStats delta = NetworkStats.subtract(snapshot, last,
6006 null, null, mTmpNetworkStats);
6007 mTmpNetworkStats = delta;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006008
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006009 long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked(
6010 elapsedRealtimeMs);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006011 long totalPackets = delta.getTotalPackets();
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006012
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006013 final int size = delta.size();
6014 for (int i = 0; i < size; i++) {
6015 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006016
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006017 if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006018
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006019 final Uid u = getUidStatsLocked(mapUid(entry.uid));
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006020 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
6021 entry.rxPackets);
6022 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
6023 entry.txPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006024
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006025 if (radioTime > 0) {
6026 // Distribute total radio active time in to this app.
6027 long appPackets = entry.rxPackets + entry.txPackets;
6028 long appRadioTime = (radioTime*appPackets)/totalPackets;
6029 u.noteMobileRadioActiveTimeLocked(appRadioTime);
6030 // Remove this app from the totals, so that we don't lose any time
6031 // due to rounding.
6032 radioTime -= appRadioTime;
6033 totalPackets -= appPackets;
6034 }
6035
6036 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
6037 entry.rxBytes);
6038 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
6039 entry.txBytes);
6040 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
6041 entry.rxPackets);
6042 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
6043 entry.txPackets);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006044 }
6045
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006046 if (radioTime > 0) {
6047 // Whoops, there is some radio time we can't blame on an app!
6048 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
6049 mMobileRadioActiveUnknownCount.addCountLocked(1);
6050 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006051 }
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006052 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006053
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006054 if ((which&NET_UPDATE_WIFI) != 0 && mWifiIfaces.length > 0) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006055 final NetworkStats snapshot;
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006056 final NetworkStats last = mCurWifiSnapshot;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006057 try {
6058 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
6059 mWifiIfaces, NetworkStats.TAG_NONE, mLastWifiSnapshot);
6060 } catch (IOException e) {
6061 Log.wtf(TAG, "Failed to read wifi network stats", e);
6062 return;
6063 }
6064
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006065 mCurWifiSnapshot = snapshot;
6066 mLastWifiSnapshot = last;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006067
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006068 if (mOnBatteryInternal) {
6069 final NetworkStats delta = NetworkStats.subtract(snapshot, last,
6070 null, null, mTmpNetworkStats);
6071 mTmpNetworkStats = delta;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006072
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006073 final int size = delta.size();
6074 for (int i = 0; i < size; i++) {
6075 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006076
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006077 if (DEBUG) {
6078 final NetworkStats.Entry cur = snapshot.getValues(i, null);
6079 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
6080 + " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes
6081 + " tx=" + cur.txBytes);
6082 }
6083
6084 if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
6085
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006086 final Uid u = getUidStatsLocked(mapUid(entry.uid));
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006087 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
6088 entry.rxPackets);
6089 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
6090 entry.txPackets);
6091
6092 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
6093 entry.rxBytes);
6094 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
6095 entry.txBytes);
6096 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
6097 entry.rxPackets);
6098 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
6099 entry.txPackets);
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006100 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006101 }
6102 }
6103 }
6104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006105 public long getAwakeTimeBattery() {
6106 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
6107 }
6108
6109 public long getAwakeTimePlugged() {
6110 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
6111 }
6112
6113 @Override
6114 public long computeUptime(long curTime, int which) {
6115 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006116 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006117 case STATS_LAST: return mLastUptime;
6118 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006119 case STATS_SINCE_UNPLUGGED: return (curTime- mOnBatteryTimeBase.getUptimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006120 }
6121 return 0;
6122 }
6123
6124 @Override
6125 public long computeRealtime(long curTime, int which) {
6126 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006127 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006128 case STATS_LAST: return mLastRealtime;
6129 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006130 case STATS_SINCE_UNPLUGGED: return (curTime- mOnBatteryTimeBase.getRealtimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006131 }
6132 return 0;
6133 }
6134
6135 @Override
6136 public long computeBatteryUptime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006137 return mOnBatteryTimeBase.computeUptime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006138 }
6139
6140 @Override
6141 public long computeBatteryRealtime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006142 return mOnBatteryTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006143 }
6144
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006145 @Override
6146 public long computeBatteryScreenOffUptime(long curTime, int which) {
6147 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
6148 }
6149
6150 @Override
6151 public long computeBatteryScreenOffRealtime(long curTime, int which) {
6152 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006153 }
6154
6155 long getBatteryUptimeLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006156 return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006157 }
6158
6159 @Override
6160 public long getBatteryUptime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006161 return mOnBatteryTimeBase.getUptime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006162 }
6163
6164 @Override
6165 public long getBatteryRealtime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006166 return mOnBatteryTimeBase.getRealtime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006167 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07006168
The Android Open Source Project10592532009-03-18 17:39:46 -07006169 @Override
Evan Millar633a1742009-04-02 16:36:33 -07006170 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07006171 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07006172 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07006173 }
6174 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006175
Evan Millar633a1742009-04-02 16:36:33 -07006176 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006177 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07006178 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006179
The Android Open Source Project10592532009-03-18 17:39:46 -07006180 @Override
Evan Millar633a1742009-04-02 16:36:33 -07006181 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07006182 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07006183 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07006184 }
6185 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006186
Evan Millar633a1742009-04-02 16:36:33 -07006187 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08006188 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07006189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006190
Amith Yamasanie43530a2009-08-21 13:11:37 -07006191 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006192 public int getLowDischargeAmountSinceCharge() {
6193 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08006194 int val = mLowDischargeAmountSinceCharge;
6195 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
6196 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
6197 }
6198 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006199 }
6200 }
6201
6202 @Override
6203 public int getHighDischargeAmountSinceCharge() {
6204 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08006205 int val = mHighDischargeAmountSinceCharge;
6206 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
6207 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
6208 }
6209 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006210 }
6211 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07006212
6213 @Override
6214 public int getDischargeAmount(int which) {
6215 int dischargeAmount = which == STATS_SINCE_CHARGED
6216 ? getHighDischargeAmountSinceCharge()
6217 : (getDischargeStartLevel() - getDischargeCurrentLevel());
6218 if (dischargeAmount < 0) {
6219 dischargeAmount = 0;
6220 }
6221 return dischargeAmount;
6222 }
6223
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006224 public int getDischargeAmountScreenOn() {
6225 synchronized(this) {
6226 int val = mDischargeAmountScreenOn;
6227 if (mOnBattery && mScreenOn
6228 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
6229 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
6230 }
6231 return val;
6232 }
6233 }
6234
6235 public int getDischargeAmountScreenOnSinceCharge() {
6236 synchronized(this) {
6237 int val = mDischargeAmountScreenOnSinceCharge;
6238 if (mOnBattery && mScreenOn
6239 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
6240 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
6241 }
6242 return val;
6243 }
6244 }
6245
6246 public int getDischargeAmountScreenOff() {
6247 synchronized(this) {
6248 int val = mDischargeAmountScreenOff;
6249 if (mOnBattery && !mScreenOn
6250 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
6251 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
6252 }
6253 return val;
6254 }
6255 }
6256
6257 public int getDischargeAmountScreenOffSinceCharge() {
6258 synchronized(this) {
6259 int val = mDischargeAmountScreenOffSinceCharge;
6260 if (mOnBattery && !mScreenOn
6261 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
6262 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
6263 }
6264 return val;
6265 }
6266 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006267
6268 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07006269 public int getCpuSpeedSteps() {
6270 return sNumSpeedSteps;
6271 }
6272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006273 /**
6274 * Retrieve the statistics object for a particular uid, creating if needed.
6275 */
6276 public Uid getUidStatsLocked(int uid) {
6277 Uid u = mUidStats.get(uid);
6278 if (u == null) {
6279 u = new Uid(uid);
6280 mUidStats.put(uid, u);
6281 }
6282 return u;
6283 }
6284
6285 /**
6286 * Remove the statistics object for a particular uid.
6287 */
6288 public void removeUidStatsLocked(int uid) {
6289 mUidStats.remove(uid);
6290 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07006291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006292 /**
6293 * Retrieve the statistics object for a particular process, creating
6294 * if needed.
6295 */
6296 public Uid.Proc getProcessStatsLocked(int uid, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006297 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006298 Uid u = getUidStatsLocked(uid);
6299 return u.getProcessStatsLocked(name);
6300 }
6301
6302 /**
6303 * Retrieve the statistics object for a particular process, creating
6304 * if needed.
6305 */
6306 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006307 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006308 Uid u = getUidStatsLocked(uid);
6309 return u.getPackageStatsLocked(pkg);
6310 }
6311
6312 /**
6313 * Retrieve the statistics object for a particular service, creating
6314 * if needed.
6315 */
6316 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006317 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006318 Uid u = getUidStatsLocked(uid);
6319 return u.getServiceStatsLocked(pkg, name);
6320 }
6321
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006322 /**
6323 * Massage data to distribute any reasonable work down to more specific
6324 * owners. Must only be called on a dead BatteryStats object!
6325 */
6326 public void distributeWorkLocked(int which) {
6327 // Aggregate all CPU time associated with WIFI.
6328 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
6329 if (wifiUid != null) {
6330 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
6331 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
6332 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
6333 for (int i=0; i<mUidStats.size(); i++) {
6334 Uid uid = mUidStats.valueAt(i);
6335 if (uid.mUid != Process.WIFI_UID) {
6336 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
6337 if (uidRunningTime > 0) {
6338 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
6339 long time = proc.getUserTime(which);
6340 time = (time*uidRunningTime)/totalRunningTime;
6341 uidProc.mUserTime += time;
6342 proc.mUserTime -= time;
6343 time = proc.getSystemTime(which);
6344 time = (time*uidRunningTime)/totalRunningTime;
6345 uidProc.mSystemTime += time;
6346 proc.mSystemTime -= time;
6347 time = proc.getForegroundTime(which);
6348 time = (time*uidRunningTime)/totalRunningTime;
6349 uidProc.mForegroundTime += time;
6350 proc.mForegroundTime -= time;
6351 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
6352 SamplingCounter sc = proc.mSpeedBins[sb];
6353 if (sc != null) {
6354 time = sc.getCountLocked(which);
6355 time = (time*uidRunningTime)/totalRunningTime;
6356 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
6357 if (uidSc == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006358 uidSc = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006359 uidProc.mSpeedBins[sb] = uidSc;
6360 }
6361 uidSc.mCount.addAndGet((int)time);
6362 sc.mCount.addAndGet((int)-time);
6363 }
6364 }
6365 totalRunningTime -= uidRunningTime;
6366 }
6367 }
6368 }
6369 }
6370 }
6371 }
6372
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006373 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006374 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006375 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006376 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006377
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006378 Parcel mPendingWrite = null;
6379 final ReentrantLock mWriteLock = new ReentrantLock();
6380
6381 public void writeAsyncLocked() {
6382 writeLocked(false);
6383 }
6384
6385 public void writeSyncLocked() {
6386 writeLocked(true);
6387 }
6388
6389 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006390 if (mFile == null) {
6391 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006392 return;
6393 }
6394
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006395 if (mShuttingDown) {
6396 return;
6397 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006398
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006399 Parcel out = Parcel.obtain();
6400 writeSummaryToParcel(out);
6401 mLastWriteTime = SystemClock.elapsedRealtime();
6402
6403 if (mPendingWrite != null) {
6404 mPendingWrite.recycle();
6405 }
6406 mPendingWrite = out;
6407
6408 if (sync) {
6409 commitPendingDataToDisk();
6410 } else {
6411 Thread thr = new Thread("BatteryStats-Write") {
6412 @Override
6413 public void run() {
6414 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
6415 commitPendingDataToDisk();
6416 }
6417 };
6418 thr.start();
6419 }
6420 }
6421
6422 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07006423 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006424 synchronized (this) {
6425 next = mPendingWrite;
6426 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07006427 if (next == null) {
6428 return;
6429 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006430
6431 mWriteLock.lock();
6432 }
6433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006434 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006435 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006436 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006437 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006438 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006439 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006440 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006441 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006442 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006443 mFile.rollback();
6444 } finally {
6445 next.recycle();
6446 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07006447 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006448 }
6449
6450 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
6451 int pos = 0;
6452 int avail = stream.available();
6453 byte[] data = new byte[avail];
6454 while (true) {
6455 int amt = stream.read(data, pos, data.length-pos);
6456 //Log.i("foo", "Read " + amt + " bytes at " + pos
6457 // + " of avail " + data.length);
6458 if (amt <= 0) {
6459 //Log.i("foo", "**** FINISHED READING: pos=" + pos
6460 // + " len=" + data.length);
6461 return data;
6462 }
6463 pos += amt;
6464 avail = stream.available();
6465 if (avail > data.length-pos) {
6466 byte[] newData = new byte[pos+avail];
6467 System.arraycopy(data, 0, newData, 0, pos);
6468 data = newData;
6469 }
6470 }
6471 }
6472
6473 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006474 if (mFile == null) {
6475 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006476 return;
6477 }
6478
6479 mUidStats.clear();
6480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006481 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006482 File file = mFile.chooseForRead();
6483 if (!file.exists()) {
6484 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006485 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006486 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006487
6488 byte[] raw = readFully(stream);
6489 Parcel in = Parcel.obtain();
6490 in.unmarshall(raw, 0, raw.length);
6491 in.setDataPosition(0);
6492 stream.close();
6493
6494 readSummaryFromParcel(in);
Dianne Hackborn00e25212014-02-19 10:49:24 -08006495 } catch(Exception e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006496 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006497 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006498
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006499 if (mHistoryBuffer.dataPosition() > 0) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07006500 final long elapsedRealtime = SystemClock.elapsedRealtime();
6501 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006502 if (USE_OLD_HISTORY) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07006503 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006504 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07006505 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006506 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn40c87252014-03-19 16:55:40 -07006507 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_CURRENT_TIME);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006508 mHistoryCur.currentTime = 0;
Dianne Hackborne8c88e62011-08-17 19:09:09 -07006509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006510 }
6511
6512 public int describeContents() {
6513 return 0;
6514 }
6515
Dianne Hackbornae384452011-06-28 12:33:48 -07006516 void readHistory(Parcel in, boolean andOldHistory) {
6517 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006518
6519 mHistoryBuffer.setDataSize(0);
6520 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006521 mHistoryTagPool.clear();
6522 mNextHistoryTagIdx = 0;
6523 mNumHistoryTagChars = 0;
Dianne Hackborn099bc622014-01-22 13:39:16 -08006524
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006525 int numTags = in.readInt();
6526 for (int i=0; i<numTags; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08006527 int idx = in.readInt();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006528 String str = in.readString();
6529 int uid = in.readInt();
6530 HistoryTag tag = new HistoryTag();
6531 tag.string = str;
6532 tag.uid = uid;
6533 tag.poolIdx = idx;
6534 mHistoryTagPool.put(tag, idx);
6535 if (idx >= mNextHistoryTagIdx) {
6536 mNextHistoryTagIdx = idx+1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08006537 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006538 mNumHistoryTagChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08006539 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006540
6541 int bufSize = in.readInt();
6542 int curPos = in.dataPosition();
6543 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
6544 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
6545 } else if ((bufSize&~3) != bufSize) {
6546 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
6547 } else {
6548 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
6549 + " bytes at " + curPos);
6550 mHistoryBuffer.appendFrom(in, curPos, bufSize);
6551 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006552 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006553
Dianne Hackbornae384452011-06-28 12:33:48 -07006554 if (andOldHistory) {
6555 readOldHistory(in);
6556 }
6557
6558 if (DEBUG_HISTORY) {
6559 StringBuilder sb = new StringBuilder(128);
6560 sb.append("****************** OLD mHistoryBaseTime: ");
6561 TimeUtils.formatDuration(mHistoryBaseTime, sb);
6562 Slog.i(TAG, sb.toString());
6563 }
6564 mHistoryBaseTime = historyBaseTime;
6565 if (DEBUG_HISTORY) {
6566 StringBuilder sb = new StringBuilder(128);
6567 sb.append("****************** NEW mHistoryBaseTime: ");
6568 TimeUtils.formatDuration(mHistoryBaseTime, sb);
6569 Slog.i(TAG, sb.toString());
6570 }
6571
6572 // We are just arbitrarily going to insert 1 minute from the sample of
6573 // the last run until samples in this run.
6574 if (mHistoryBaseTime > 0) {
6575 long oldnow = SystemClock.elapsedRealtime();
6576 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000;
6577 if (DEBUG_HISTORY) {
6578 StringBuilder sb = new StringBuilder(128);
6579 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
6580 TimeUtils.formatDuration(mHistoryBaseTime, sb);
6581 Slog.i(TAG, sb.toString());
6582 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07006583 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006584 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006585
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006586 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07006587 if (!USE_OLD_HISTORY) {
6588 return;
6589 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006590 mHistory = mHistoryEnd = mHistoryCache = null;
6591 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07006592 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006593 HistoryItem rec = new HistoryItem(time, in);
6594 addHistoryRecordLocked(rec);
6595 }
6596 }
6597
Dianne Hackbornae384452011-06-28 12:33:48 -07006598 void writeHistory(Parcel out, boolean andOldHistory) {
6599 if (DEBUG_HISTORY) {
6600 StringBuilder sb = new StringBuilder(128);
6601 sb.append("****************** WRITING mHistoryBaseTime: ");
6602 TimeUtils.formatDuration(mHistoryBaseTime, sb);
Dianne Hackborn40c87252014-03-19 16:55:40 -07006603 sb.append(" mLastHistoryElapsedRealtime: ");
6604 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
Dianne Hackbornae384452011-06-28 12:33:48 -07006605 Slog.i(TAG, sb.toString());
6606 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07006607 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006608 out.writeInt(mHistoryTagPool.size());
6609 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
6610 HistoryTag tag = ent.getKey();
Dianne Hackborn099bc622014-01-22 13:39:16 -08006611 out.writeInt(ent.getValue());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006612 out.writeString(tag.string);
6613 out.writeInt(tag.uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08006614 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006615 out.writeInt(mHistoryBuffer.dataSize());
6616 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
6617 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
6618 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07006619
6620 if (andOldHistory) {
6621 writeOldHistory(out);
6622 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006623 }
6624
6625 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07006626 if (!USE_OLD_HISTORY) {
6627 return;
6628 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006629 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006630 while (rec != null) {
6631 if (rec.time >= 0) rec.writeToParcel(out, 0);
6632 rec = rec.next;
6633 }
6634 out.writeLong(-1);
6635 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006637 private void readSummaryFromParcel(Parcel in) {
6638 final int version = in.readInt();
6639 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006640 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006641 + ", expected " + VERSION + "; erasing old stats");
6642 return;
6643 }
6644
Dianne Hackbornae384452011-06-28 12:33:48 -07006645 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006647 mStartCount = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006648 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006649 mRealtime = in.readLong();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08006650 mStartClockTime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006651 mOnBatteryTimeBase.readSummaryFromParcel(in);
6652 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006653 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07006654 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006655 mLowDischargeAmountSinceCharge = in.readInt();
6656 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006657 mDischargeAmountScreenOnSinceCharge = in.readInt();
6658 mDischargeAmountScreenOffSinceCharge = in.readInt();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006662 mScreenOn = false;
6663 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006664 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
6665 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
6666 }
6667 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006668 mPhoneOn = false;
6669 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08006670 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07006671 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
6672 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07006673 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006674 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
6675 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
6676 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006677 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006678 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
6679 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006680 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08006681 mMobileRadioActive = false;
6682 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006683 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006684 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
6685 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07006686 mWifiOn = false;
6687 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006688 mGlobalWifiRunning = false;
6689 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006690 for (int i=0; i<NUM_WIFI_STATES; i++) {
6691 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
6692 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006693 mBluetoothOn = false;
6694 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006695 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
6696 mBluetoothStateTimer[i].readSummaryFromParcelLocked(in);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08006697 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006698
Evan Millarc64edde2009-04-18 12:26:32 -07006699 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006700 if (NKW > 10000) {
6701 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
6702 return;
6703 }
Evan Millarc64edde2009-04-18 12:26:32 -07006704 for (int ikw = 0; ikw < NKW; ikw++) {
6705 if (in.readInt() != 0) {
6706 String kwltName = in.readString();
6707 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
6708 }
6709 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006710
6711 sNumSpeedSteps = in.readInt();
Dianne Hackborn00e25212014-02-19 10:49:24 -08006712 if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) {
6713 throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps);
6714 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006717 if (NU > 10000) {
6718 Slog.w(TAG, "File corrupt: too many uids " + NU);
6719 return;
6720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006721 for (int iu = 0; iu < NU; iu++) {
6722 int uid = in.readInt();
6723 Uid u = new Uid(uid);
6724 mUidStats.put(uid, u);
6725
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006726 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006727 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006728 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006729 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006730 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006731 if (in.readInt() != 0) {
6732 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
6733 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07006734 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006735 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07006736 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006737 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07006738 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
6739 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
6740 if (in.readInt() != 0) {
6741 u.makeWifiBatchedScanBin(i, null);
6742 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
6743 }
6744 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006745 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006746 if (in.readInt() != 0) {
6747 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
6748 }
6749 u.mAudioTurnedOn = false;
6750 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006751 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006752 }
6753 u.mVideoTurnedOn = false;
6754 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006755 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
6756 }
6757 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006758 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
6759 }
6760 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006761 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006762 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006763
Dianne Hackborn617f8772009-03-31 15:04:46 -07006764 if (in.readInt() != 0) {
6765 if (u.mUserActivityCounters == null) {
6766 u.initUserActivityLocked();
6767 }
6768 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
6769 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
6770 }
6771 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006772
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006773 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006774 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006775 u.initNetworkActivityLocked();
6776 }
6777 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006778 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
6779 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006780 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006781 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
6782 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006783 }
6784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08006786 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006787 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
6788 return;
6789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006790 for (int iw = 0; iw < NW; iw++) {
6791 String wlName = in.readString();
6792 if (in.readInt() != 0) {
6793 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
6794 }
6795 if (in.readInt() != 0) {
6796 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
6797 }
6798 if (in.readInt() != 0) {
6799 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
6800 }
6801 }
6802
6803 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08006804 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006805 Slog.w(TAG, "File corrupt: too many sensors " + NP);
6806 return;
6807 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006808 for (int is = 0; is < NP; is++) {
6809 int seNumber = in.readInt();
6810 if (in.readInt() != 0) {
6811 u.getSensorTimerLocked(seNumber, true)
6812 .readSummaryFromParcelLocked(in);
6813 }
6814 }
6815
6816 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08006817 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006818 Slog.w(TAG, "File corrupt: too many processes " + NP);
6819 return;
6820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006821 for (int ip = 0; ip < NP; ip++) {
6822 String procName = in.readString();
6823 Uid.Proc p = u.getProcessStatsLocked(procName);
6824 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006825 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006826 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006827 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006828 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08006829 if (NSB > 100) {
6830 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
6831 return;
6832 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006833 p.mSpeedBins = new SamplingCounter[NSB];
6834 for (int i=0; i<NSB; i++) {
6835 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006836 p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006837 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
6838 }
6839 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08006840 if (!p.readExcessivePowerFromParcelLocked(in)) {
6841 return;
6842 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006843 }
6844
6845 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006846 if (NP > 10000) {
6847 Slog.w(TAG, "File corrupt: too many packages " + NP);
6848 return;
6849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006850 for (int ip = 0; ip < NP; ip++) {
6851 String pkgName = in.readString();
6852 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
6853 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006854 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08006855 if (NS > 1000) {
6856 Slog.w(TAG, "File corrupt: too many services " + NS);
6857 return;
6858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006859 for (int is = 0; is < NS; is++) {
6860 String servName = in.readString();
6861 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
6862 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006863 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006864 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006865 }
6866 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006867 }
6868 }
6869
6870 /**
6871 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
6872 * disk. This format does not allow a lossless round-trip.
6873 *
6874 * @param out the Parcel to be written to.
6875 */
6876 public void writeSummaryToParcel(Parcel out) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08006877 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006879 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
6880 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006881
6882 out.writeInt(VERSION);
6883
Dianne Hackbornae384452011-06-28 12:33:48 -07006884 writeHistory(out, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006886 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006887 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006888 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08006889 out.writeLong(mStartClockTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006890 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
6891 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006892 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07006893 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08006894 out.writeInt(getLowDischargeAmountSinceCharge());
6895 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006896 out.writeInt(getDischargeAmountScreenOnSinceCharge());
6897 out.writeInt(getDischargeAmountScreenOffSinceCharge());
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006898
6899 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006900 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006901 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006902 }
6903 mInputEventCounter.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006904 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Wink Saville52840902011-02-18 12:40:47 -08006905 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006906 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006907 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006908 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006909 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006910 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006911 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006912 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006913 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
6914 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006915 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006916 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
6917 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006918 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
6919 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006920 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
6921 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006922 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006923 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006924 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006925 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006926 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006927 mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08006928 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006929
Evan Millarc64edde2009-04-18 12:26:32 -07006930 out.writeInt(mKernelWakelockStats.size());
6931 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
6932 Timer kwlt = ent.getValue();
6933 if (kwlt != null) {
6934 out.writeInt(1);
6935 out.writeString(ent.getKey());
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006936 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Evan Millarc64edde2009-04-18 12:26:32 -07006937 } else {
6938 out.writeInt(0);
6939 }
6940 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006941
Amith Yamasanie43530a2009-08-21 13:11:37 -07006942 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006943 final int NU = mUidStats.size();
6944 out.writeInt(NU);
6945 for (int iu = 0; iu < NU; iu++) {
6946 out.writeInt(mUidStats.keyAt(iu));
6947 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006948
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006949 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006950 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006951 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006952 } else {
6953 out.writeInt(0);
6954 }
6955 if (u.mFullWifiLockTimer != null) {
6956 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006957 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006958 } else {
6959 out.writeInt(0);
6960 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07006961 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006962 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006963 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006964 } else {
6965 out.writeInt(0);
6966 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07006967 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
6968 if (u.mWifiBatchedScanTimer[i] != null) {
6969 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006970 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006971 } else {
6972 out.writeInt(0);
6973 }
6974 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006975 if (u.mWifiMulticastTimer != null) {
6976 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006977 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006978 } else {
6979 out.writeInt(0);
6980 }
6981 if (u.mAudioTurnedOnTimer != null) {
6982 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006983 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006984 } else {
6985 out.writeInt(0);
6986 }
6987 if (u.mVideoTurnedOnTimer != null) {
6988 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006989 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006990 } else {
6991 out.writeInt(0);
6992 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006993 if (u.mForegroundActivityTimer != null) {
6994 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006995 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006996 } else {
6997 out.writeInt(0);
6998 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006999 if (u.mVibratorOnTimer != null) {
7000 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007001 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007002 } else {
7003 out.writeInt(0);
7004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007005
Dianne Hackborn617f8772009-03-31 15:04:46 -07007006 if (u.mUserActivityCounters == null) {
7007 out.writeInt(0);
7008 } else {
7009 out.writeInt(1);
7010 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
7011 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
7012 }
7013 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007014
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007015 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007016 out.writeInt(0);
7017 } else {
7018 out.writeInt(1);
7019 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007020 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
7021 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007022 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007023 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
7024 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007025 }
7026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 int NW = u.mWakelockStats.size();
7028 out.writeInt(NW);
7029 if (NW > 0) {
7030 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
7031 : u.mWakelockStats.entrySet()) {
7032 out.writeString(ent.getKey());
7033 Uid.Wakelock wl = ent.getValue();
7034 if (wl.mTimerFull != null) {
7035 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007036 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007037 } else {
7038 out.writeInt(0);
7039 }
7040 if (wl.mTimerPartial != null) {
7041 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007042 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007043 } else {
7044 out.writeInt(0);
7045 }
7046 if (wl.mTimerWindow != null) {
7047 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007048 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007049 } else {
7050 out.writeInt(0);
7051 }
7052 }
7053 }
7054
7055 int NSE = u.mSensorStats.size();
7056 out.writeInt(NSE);
7057 if (NSE > 0) {
7058 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
7059 : u.mSensorStats.entrySet()) {
7060 out.writeInt(ent.getKey());
7061 Uid.Sensor se = ent.getValue();
7062 if (se.mTimer != null) {
7063 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007064 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007065 } else {
7066 out.writeInt(0);
7067 }
7068 }
7069 }
7070
7071 int NP = u.mProcessStats.size();
7072 out.writeInt(NP);
7073 if (NP > 0) {
7074 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
7075 : u.mProcessStats.entrySet()) {
7076 out.writeString(ent.getKey());
7077 Uid.Proc ps = ent.getValue();
7078 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 out.writeLong(ps.mSystemTime);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007080 out.writeLong(ps.mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007081 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007082 final int N = ps.mSpeedBins.length;
7083 out.writeInt(N);
7084 for (int i=0; i<N; i++) {
7085 if (ps.mSpeedBins[i] != null) {
7086 out.writeInt(1);
7087 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
7088 } else {
7089 out.writeInt(0);
7090 }
7091 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007092 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007093 }
7094 }
7095
7096 NP = u.mPackageStats.size();
7097 out.writeInt(NP);
7098 if (NP > 0) {
7099 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
7100 : u.mPackageStats.entrySet()) {
7101 out.writeString(ent.getKey());
7102 Uid.Pkg ps = ent.getValue();
7103 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007104 final int NS = ps.mServiceStats.size();
7105 out.writeInt(NS);
7106 if (NS > 0) {
7107 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
7108 : ps.mServiceStats.entrySet()) {
7109 out.writeString(sent.getKey());
7110 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007111 long time = ss.getStartTimeToNowLocked(
7112 mOnBatteryTimeBase.getUptime(NOW_SYS));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007113 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007114 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007115 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007116 }
7117 }
7118 }
7119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007120 }
7121 }
7122
7123 public void readFromParcel(Parcel in) {
7124 readFromParcelLocked(in);
7125 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007127 void readFromParcelLocked(Parcel in) {
7128 int magic = in.readInt();
7129 if (magic != MAGIC) {
7130 throw new ParcelFormatException("Bad magic number");
7131 }
7132
Dianne Hackbornae384452011-06-28 12:33:48 -07007133 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007135 mStartCount = in.readInt();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007136 mStartClockTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007137 mUptime = in.readLong();
7138 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007139 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007140 mRealtime = in.readLong();
7141 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007142 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007143 mOnBattery = in.readInt() != 0;
7144 mOnBatteryInternal = false; // we are no longer really running.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007145 mOnBatteryTimeBase.readFromParcel(in);
7146 mOnBatteryScreenOffTimeBase.readFromParcel(in);
7147
7148 mScreenOn = false;
7149 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase, in);
7150 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
7151 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase,
7152 in);
7153 }
7154 mInputEventCounter = new Counter(mOnBatteryTimeBase, in);
7155 mPhoneOn = false;
7156 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
7157 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
7158 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
7159 null, mOnBatteryTimeBase, in);
7160 }
7161 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase, in);
7162 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
7163 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
7164 null, mOnBatteryTimeBase, in);
7165 }
7166 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
7167 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
7168 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
7169 }
7170 mMobileRadioActive = false;
7171 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in);
7172 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase,
7173 in);
7174 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
7175 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
7176 mWifiOn = false;
7177 mWifiOnTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
7178 mGlobalWifiRunning = false;
7179 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
7180 for (int i=0; i<NUM_WIFI_STATES; i++) {
7181 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
7182 null, mOnBatteryTimeBase, in);
7183 }
7184 mBluetoothOn = false;
7185 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
7186 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
7187 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i,
7188 null, mOnBatteryTimeBase, in);
7189 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007190 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07007191 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007192 mLowDischargeAmountSinceCharge = in.readInt();
7193 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007194 mDischargeAmountScreenOn = in.readInt();
7195 mDischargeAmountScreenOnSinceCharge = in.readInt();
7196 mDischargeAmountScreenOff = in.readInt();
7197 mDischargeAmountScreenOffSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007198 mLastWriteTime = in.readLong();
7199
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07007200 mBluetoothPingCount = in.readInt();
7201 mBluetoothPingStart = -1;
7202
Evan Millarc64edde2009-04-18 12:26:32 -07007203 mKernelWakelockStats.clear();
7204 int NKW = in.readInt();
7205 for (int ikw = 0; ikw < NKW; ikw++) {
7206 if (in.readInt() != 0) {
7207 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07007208 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007209 SamplingTimer kwlt = new SamplingTimer(mOnBatteryTimeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07007210 mKernelWakelockStats.put(wakelockName, kwlt);
7211 }
7212 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007214 mPartialTimers.clear();
7215 mFullTimers.clear();
7216 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007217 mWifiRunningTimers.clear();
7218 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -07007219 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -07007220 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007221 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007222
Amith Yamasanie43530a2009-08-21 13:11:37 -07007223 sNumSpeedSteps = in.readInt();
7224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007225 int numUids = in.readInt();
7226 mUidStats.clear();
7227 for (int i = 0; i < numUids; i++) {
7228 int uid = in.readInt();
7229 Uid u = new Uid(uid);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007230 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007231 mUidStats.append(uid, u);
7232 }
7233 }
7234
7235 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007236 writeToParcelLocked(out, true, flags);
7237 }
7238
7239 public void writeToParcelWithoutUids(Parcel out, int flags) {
7240 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007241 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007242
7243 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007244 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007245 // Need to update with current kernel wake lock counts.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007246 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007248 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
7249 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007250 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
7251 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007253 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007254
Dianne Hackbornae384452011-06-28 12:33:48 -07007255 writeHistory(out, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007257 out.writeInt(mStartCount);
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007258 out.writeLong(mStartClockTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 out.writeLong(mUptime);
7260 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007261 out.writeLong(mRealtime);
7262 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007263 out.writeInt(mOnBattery ? 1 : 0);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007264 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
7265 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
7266
7267 mScreenOnTimer.writeToParcel(out, uSecRealtime);
7268 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
7269 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
7270 }
7271 mInputEventCounter.writeToParcel(out);
7272 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
7273 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
7274 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
7275 }
7276 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
7277 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
7278 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
7279 }
7280 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
7281 mNetworkByteActivityCounters[i].writeToParcel(out);
7282 mNetworkPacketActivityCounters[i].writeToParcel(out);
7283 }
7284 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
7285 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
7286 mMobileRadioActiveUnknownTime.writeToParcel(out);
7287 mMobileRadioActiveUnknownCount.writeToParcel(out);
7288 mWifiOnTimer.writeToParcel(out, uSecRealtime);
7289 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
7290 for (int i=0; i<NUM_WIFI_STATES; i++) {
7291 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
7292 }
7293 mBluetoothOnTimer.writeToParcel(out, uSecRealtime);
7294 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
7295 mBluetoothStateTimer[i].writeToParcel(out, uSecRealtime);
7296 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007297 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07007298 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007299 out.writeInt(mLowDischargeAmountSinceCharge);
7300 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007301 out.writeInt(mDischargeAmountScreenOn);
7302 out.writeInt(mDischargeAmountScreenOnSinceCharge);
7303 out.writeInt(mDischargeAmountScreenOff);
7304 out.writeInt(mDischargeAmountScreenOffSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007305 out.writeLong(mLastWriteTime);
7306
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07007307 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07007308
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007309 if (inclUids) {
7310 out.writeInt(mKernelWakelockStats.size());
7311 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
7312 SamplingTimer kwlt = ent.getValue();
7313 if (kwlt != null) {
7314 out.writeInt(1);
7315 out.writeString(ent.getKey());
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007316 Timer.writeTimerToParcel(out, kwlt, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007317 } else {
7318 out.writeInt(0);
7319 }
Evan Millarc64edde2009-04-18 12:26:32 -07007320 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007321 } else {
7322 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07007323 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07007324
7325 out.writeInt(sNumSpeedSteps);
7326
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007327 if (inclUids) {
7328 int size = mUidStats.size();
7329 out.writeInt(size);
7330 for (int i = 0; i < size; i++) {
7331 out.writeInt(mUidStats.keyAt(i));
7332 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007333
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007334 uid.writeToParcelLocked(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007335 }
7336 } else {
7337 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007338 }
7339 }
7340
7341 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
7342 new Parcelable.Creator<BatteryStatsImpl>() {
7343 public BatteryStatsImpl createFromParcel(Parcel in) {
7344 return new BatteryStatsImpl(in);
7345 }
7346
7347 public BatteryStatsImpl[] newArray(int size) {
7348 return new BatteryStatsImpl[size];
7349 }
7350 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007351
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007352 public void prepareForDumpLocked() {
7353 // Need to retrieve current kernel wake lock stats before printing.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007354 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007355 }
7356
Dianne Hackbornc51cf032014-03-02 19:08:15 -08007357 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007358 if (DEBUG) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007359 pw.println("mOnBatteryTimeBase:");
7360 mOnBatteryTimeBase.dump(pw, " ");
7361 pw.println("mOnBatteryScreenOffTimeBase:");
7362 mOnBatteryScreenOffTimeBase.dump(pw, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007363 Printer pr = new PrintWriterPrinter(pw);
7364 pr.println("*** Screen timer:");
7365 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07007366 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007367 pr.println("*** Screen brightness #" + i + ":");
7368 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07007369 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007370 pr.println("*** Input event counter:");
7371 mInputEventCounter.logState(pr, " ");
7372 pr.println("*** Phone timer:");
7373 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08007374 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007375 pr.println("*** Signal strength #" + i + ":");
7376 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07007377 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07007378 pr.println("*** Signal scanning :");
7379 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07007380 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007381 pr.println("*** Data connection type #" + i + ":");
7382 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07007383 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007384 pr.println("*** Mobile network active timer:");
7385 mMobileRadioActiveTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007386 pr.println("*** Wifi timer:");
7387 mWifiOnTimer.logState(pr, " ");
7388 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007389 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007390 for (int i=0; i<NUM_WIFI_STATES; i++) {
7391 pr.println("*** Wifi state #" + i + ":");
7392 mWifiStateTimer[i].logState(pr, " ");
7393 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007394 pr.println("*** Bluetooth timer:");
7395 mBluetoothOnTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007396 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007397 pr.println("*** Bluetooth active type #" + i + ":");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007398 mBluetoothStateTimer[i].logState(pr, " ");
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007400 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08007401 super.dumpLocked(context, pw, flags, reqUid, histStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007403}