blob: ed9f9bcacc59bf2592150216b1ccdfab289b907c [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;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070041import android.telephony.DataConnectionRealTimeInfo;
Amith Yamasanif37447b2009-10-08 18:28:01 -070042import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070043import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070044import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070046import android.util.LogWriter;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070047import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070049import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.util.SparseArray;
Dianne Hackborn099bc622014-01-22 13:39:16 -080051import android.util.SparseIntArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070052import android.util.TimeUtils;
Jeff Browne95c3cd2014-05-02 16:59:26 -070053import android.view.Display;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070055import com.android.internal.annotations.GuardedBy;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070056import com.android.internal.net.NetworkStatsFactory;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080057import com.android.internal.util.ArrayUtils;
Dianne Hackborn8c841092013-06-24 13:46:13 -070058import com.android.internal.util.FastPrintWriter;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070059import com.android.internal.util.JournaledFile;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import java.io.File;
62import java.io.FileInputStream;
63import java.io.FileOutputStream;
64import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070065import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import java.util.ArrayList;
67import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070068import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070069import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070071import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070072import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
74/**
75 * All information we are collecting about things that can happen that impact
76 * battery life. All times are represented in microseconds except where indicated
77 * otherwise.
78 */
79public final class BatteryStatsImpl extends BatteryStats {
80 private static final String TAG = "BatteryStatsImpl";
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080081 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070082 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -070083 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070084
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070085 // TODO: remove "tcp" from network methods, since we measure total stats.
86
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070088 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089
90 // Current on-disk Parcel version
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070091 private static final int VERSION = 106 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -070092
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070093 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070094 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070095
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070096 // No, really, THIS is the maximum number of items we will record in the history.
97 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
98
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080099 // The maximum number of names wakelocks we will keep track of
100 // per uid; once the limit is reached, we batch the remaining wakelocks
101 // in to one common name.
Dianne Hackbornaf17baa2013-05-09 15:27:47 -0700102 private static final int MAX_WAKELOCKS_PER_UID = 50;
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700103
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800104 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700105
Amith Yamasanie43530a2009-08-21 13:11:37 -0700106 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700108 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700110 static final int MSG_UPDATE_WAKELOCKS = 1;
111 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700112 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700113
114 public interface BatteryCallback {
115 public void batteryNeedsCpuUpdate();
116 public void batteryPowerChanged(boolean onBattery);
117 }
118
119 final class MyHandler extends Handler {
Jeff Brown6f357d32014-01-15 20:40:55 -0800120 public MyHandler(Looper looper) {
121 super(looper, null, true);
122 }
123
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700124 @Override
125 public void handleMessage(Message msg) {
126 BatteryCallback cb = mCallback;
127 switch (msg.what) {
128 case MSG_UPDATE_WAKELOCKS:
129 if (cb != null) {
130 cb.batteryNeedsCpuUpdate();
131 }
132 break;
133 case MSG_REPORT_POWER_CHANGE:
134 if (cb != null) {
135 cb.batteryPowerChanged(msg.arg1 != 0);
136 }
137 break;
138 }
139 }
140 }
141
142 private final MyHandler mHandler;
143
144 private BatteryCallback mCallback;
145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -0800147 * Mapping isolated uids to the actual owning app uid.
148 */
149 final SparseIntArray mIsolatedUids = new SparseIntArray();
150
151 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 * The statistics we have collected organized by uids.
153 */
154 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
155 new SparseArray<BatteryStatsImpl.Uid>();
156
157 // A set of pools of currently active timers. When a timer is queried, we will divide the
158 // elapsed time by the number of active timers to arrive at that timer's share of the time.
159 // In order to do this, we must refresh each timer whenever the number of active timers
160 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700161 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
162 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
163 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
164 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
165 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700166 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
167 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700168 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
Nick Pelly6ccaa542012-06-15 15:22:47 -0700169 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>();
Robert Greenwalta029ea12013-09-25 16:38:12 -0700170 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers =
171 new SparseArray<ArrayList<StopwatchTimer>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700173 // Last partial timers we use for distributing CPU usage.
174 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 // These are the objects that will want to do something when the device
177 // is unplugged from power.
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800178 final TimeBase mOnBatteryTimeBase = new TimeBase();
179
180 // These are the objects that will want to do something when the device
181 // is unplugged from power *and* the screen is off.
182 final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
183
184 // Set to true when we want to distribute CPU across wakelocks for the next
185 // CPU update, even if we aren't currently running wake locks.
186 boolean mDistributeWakelockCpu;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700187
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700188 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700189
Dianne Hackborn37de0982014-05-09 09:32:18 -0700190 final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800191
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700192 long mHistoryBaseTime;
193 boolean mHaveBatteryLevel = false;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700194 boolean mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700195 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 Hackborna1bd7922014-03-21 11:07:11 -0700203 final HistoryItem mHistoryAddTmp = new HistoryItem();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800204 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<HistoryTag, Integer>();
Dianne Hackborn099bc622014-01-22 13:39:16 -0800205 String[] mReadHistoryStrings;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800206 int[] mReadHistoryUids;
207 int mReadHistoryChars;
208 int mNextHistoryTagIdx = 0;
209 int mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700210 int mHistoryBufferLastPos = -1;
211 boolean mHistoryOverflow = false;
Dianne Hackborn40c87252014-03-19 16:55:40 -0700212 long mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700213 long mTrackRunningHistoryElapsedRealtime = 0;
214 long mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700215
216 final HistoryItem mHistoryCur = new HistoryItem();
217
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700218 HistoryItem mHistory;
219 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700220 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700221 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700222
223 private HistoryItem mHistoryIterator;
224 private boolean mReadOverflow;
225 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 int mStartCount;
228
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800229 long mStartClockTime;
230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 long mUptime;
232 long mUptimeStart;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 long mRealtime;
234 long mRealtimeStart;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700235
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800236 int mWakeLockNesting;
237 boolean mWakeLockImportant;
Dianne Hackborn9a755432014-05-15 17:05:22 -0700238 boolean mRecordAllWakeLocks;
239 boolean mNoAutoReset;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800240
Jeff Browne95c3cd2014-05-02 16:59:26 -0700241 int mScreenState = Display.STATE_UNKNOWN;
Evan Millarc64edde2009-04-18 12:26:32 -0700242 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700243
Dianne Hackborn617f8772009-03-31 15:04:46 -0700244 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700245 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700246
Jeff Browne95c3cd2014-05-02 16:59:26 -0700247 boolean mInteractive;
248 StopwatchTimer mInteractiveTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700249
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700250 boolean mLowPowerModeEnabled;
251 StopwatchTimer mLowPowerModeEnabledTimer;
252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700254 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700255
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700256 boolean mAudioOn;
257 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700258
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700259 boolean mVideoOn;
260 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700261
Dianne Hackborn627bba72009-03-24 22:32:56 -0700262 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800263 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700264 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800265 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700266
267 StopwatchTimer mPhoneSignalScanningTimer;
268
Dianne Hackborn627bba72009-03-24 22:32:56 -0700269 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700270 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700271 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700272
Dianne Hackborn57ed6a62013-12-09 18:15:56 -0800273 final LongSamplingCounter[] mNetworkByteActivityCounters =
274 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
275 final LongSamplingCounter[] mNetworkPacketActivityCounters =
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700276 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
277
The Android Open Source Project10592532009-03-18 17:39:46 -0700278 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700279 StopwatchTimer mWifiOnTimer;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700280
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700281 boolean mGlobalWifiRunning;
282 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700283
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800284 int mWifiState = -1;
285 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
286
The Android Open Source Project10592532009-03-18 17:39:46 -0700287 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700288 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700289
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800290 int mBluetoothState = -1;
291 final StopwatchTimer[] mBluetoothStateTimer = new StopwatchTimer[NUM_BLUETOOTH_STATES];
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800292
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700293 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800294 StopwatchTimer mMobileRadioActiveTimer;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800295 StopwatchTimer mMobileRadioActivePerAppTimer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700296 LongSamplingCounter mMobileRadioActiveAdjustedTime;
Dianne Hackbornd45665b2014-02-26 12:35:32 -0800297 LongSamplingCounter mMobileRadioActiveUnknownTime;
298 LongSamplingCounter mMobileRadioActiveUnknownCount;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800299
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700300 /** Bluetooth headset object */
301 BluetoothHeadset mBtHeadset;
302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 /**
304 * These provide time bases that discount the time the device is plugged
305 * in to power.
306 */
307 boolean mOnBattery;
308 boolean mOnBatteryInternal;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700309
The Android Open Source Project10592532009-03-18 17:39:46 -0700310 /*
311 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
312 */
Evan Millar633a1742009-04-02 16:36:33 -0700313 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700314 int mDischargeUnplugLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700315 int mDischargePlugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700316 int mDischargeCurrentLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700317 int mCurrentBatteryLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700318 int mLowDischargeAmountSinceCharge;
319 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800320 int mDischargeScreenOnUnplugLevel;
321 int mDischargeScreenOffUnplugLevel;
322 int mDischargeAmountScreenOn;
323 int mDischargeAmountScreenOnSinceCharge;
324 int mDischargeAmountScreenOff;
325 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700326
Dianne Hackborn260c5022014-04-29 11:23:16 -0700327 static final int MAX_LEVEL_STEPS = 100;
328
329 int mLastDischargeStepLevel;
330 long mLastDischargeStepTime;
Dianne Hackborn29325132014-05-21 15:01:03 -0700331 int mMinDischargeStepLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700332 int mNumDischargeStepDurations;
333 final long[] mDischargeStepDurations = new long[MAX_LEVEL_STEPS];
334
335 int mLastChargeStepLevel;
336 long mLastChargeStepTime;
Dianne Hackborn29325132014-05-21 15:01:03 -0700337 int mMaxChargeStepLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700338 int mNumChargeStepDurations;
339 final long[] mChargeStepDurations = new long[MAX_LEVEL_STEPS];
340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700342
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700343 private int mBluetoothPingCount;
344 private int mBluetoothPingStart = -1;
345
Amith Yamasanif37447b2009-10-08 18:28:01 -0700346 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800347 private int mPhoneServiceStateRaw = -1;
348 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700349
Evan Millarc64edde2009-04-18 12:26:32 -0700350 /*
351 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
352 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700353 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700354 new HashMap<String, SamplingTimer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700355
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700356 public Map<String, ? extends Timer> getKernelWakelockStats() {
Evan Millarc64edde2009-04-18 12:26:32 -0700357 return mKernelWakelockStats;
358 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700359
Evan Millarc64edde2009-04-18 12:26:32 -0700360 private static int sKernelWakelockUpdateVersion = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700361
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700362 String mLastWakeupReason = null;
363 long mLastWakeupUptimeMs = 0;
364 private final HashMap<String, LongSamplingCounter> mWakeupReasonStats =
365 new HashMap<String, LongSamplingCounter>();
366
367 public Map<String, ? extends LongCounter> getWakeupReasonStats() {
368 return mWakeupReasonStats;
369 }
370
Evan Millarc64edde2009-04-18 12:26:32 -0700371 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
Dianne Hackborn13ac0412013-06-25 19:34:49 -0700372 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name
373 Process.PROC_QUOTES,
Evan Millarc64edde2009-04-18 12:26:32 -0700374 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
375 Process.PROC_TAB_TERM,
376 Process.PROC_TAB_TERM,
377 Process.PROC_TAB_TERM,
378 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
379 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700380
Todd Poynor73f534a2012-06-19 11:07:26 -0700381 private static final int[] WAKEUP_SOURCES_FORMAT = new int[] {
382 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
383 Process.PROC_TAB_TERM|Process.PROC_COMBINE|
384 Process.PROC_OUT_LONG, // 1: count
385 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
386 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
387 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
388 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
389 Process.PROC_TAB_TERM|Process.PROC_COMBINE
390 |Process.PROC_OUT_LONG, // 6: totalTime
391 };
392
Evan Millarc64edde2009-04-18 12:26:32 -0700393 private final String[] mProcWakelocksName = new String[3];
394 private final long[] mProcWakelocksData = new long[3];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700395
Evan Millarc64edde2009-04-18 12:26:32 -0700396 /*
397 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
398 * to mKernelWakelockStats.
399 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700400 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700401 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700403 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -0800404 private NetworkStats mCurMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
405 private NetworkStats mLastMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
406 private NetworkStats mCurWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
407 private NetworkStats mLastWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -0800408 private NetworkStats mTmpNetworkStats;
409 private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700410
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700411 @GuardedBy("this")
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -0800412 private String[] mMobileIfaces = new String[0];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700413 @GuardedBy("this")
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -0800414 private String[] mWifiIfaces = new String[0];
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 // For debugging
417 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700418 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700419 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 }
421
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800422 public static interface TimeBaseObs {
423 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
424 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
425 }
426
427 static class TimeBase {
428 private final ArrayList<TimeBaseObs> mObservers = new ArrayList<TimeBaseObs>();
429
430 private long mUptime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800431 private long mRealtime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800432
433 private boolean mRunning;
434
435 private long mPastUptime;
436 private long mUptimeStart;
437 private long mPastRealtime;
438 private long mRealtimeStart;
439 private long mUnpluggedUptime;
440 private long mUnpluggedRealtime;
441
442 public void dump(PrintWriter pw, String prefix) {
443 StringBuilder sb = new StringBuilder(128);
444 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
445 sb.setLength(0);
446 sb.append(prefix);
447 sb.append("mUptime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700448 formatTimeMs(sb, mUptime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800449 pw.println(sb.toString());
450 sb.setLength(0);
451 sb.append(prefix);
452 sb.append("mRealtime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700453 formatTimeMs(sb, mRealtime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800454 pw.println(sb.toString());
455 sb.setLength(0);
456 sb.append(prefix);
457 sb.append("mPastUptime=");
458 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
459 formatTimeMs(sb, mUptimeStart / 1000);
460 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
461 pw.println(sb.toString());
462 sb.setLength(0);
463 sb.append(prefix);
464 sb.append("mPastRealtime=");
465 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
466 formatTimeMs(sb, mRealtimeStart / 1000);
467 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
468 pw.println(sb.toString());
469 }
470
471 public void add(TimeBaseObs observer) {
472 mObservers.add(observer);
473 }
474
475 public void remove(TimeBaseObs observer) {
476 if (!mObservers.remove(observer)) {
477 Slog.wtf(TAG, "Removed unknown observer: " + observer);
478 }
479 }
480
481 public void init(long uptime, long realtime) {
482 mRealtime = 0;
483 mUptime = 0;
484 mPastUptime = 0;
485 mPastRealtime = 0;
486 mUptimeStart = uptime;
487 mRealtimeStart = realtime;
488 mUnpluggedUptime = getUptime(mUptimeStart);
489 mUnpluggedRealtime = getRealtime(mRealtimeStart);
490 }
491
492 public void reset(long uptime, long realtime) {
493 if (!mRunning) {
494 mPastUptime = 0;
495 mPastRealtime = 0;
496 } else {
497 mUptimeStart = uptime;
498 mRealtimeStart = realtime;
499 mUnpluggedUptime = getUptime(uptime);
500 mUnpluggedRealtime = getRealtime(realtime);
501 }
502 }
503
504 public long computeUptime(long curTime, int which) {
505 switch (which) {
506 case STATS_SINCE_CHARGED:
507 return mUptime + getUptime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800508 case STATS_CURRENT:
509 return getUptime(curTime);
510 case STATS_SINCE_UNPLUGGED:
511 return getUptime(curTime) - mUnpluggedUptime;
512 }
513 return 0;
514 }
515
516 public long computeRealtime(long curTime, int which) {
517 switch (which) {
518 case STATS_SINCE_CHARGED:
519 return mRealtime + getRealtime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800520 case STATS_CURRENT:
521 return getRealtime(curTime);
522 case STATS_SINCE_UNPLUGGED:
523 return getRealtime(curTime) - mUnpluggedRealtime;
524 }
525 return 0;
526 }
527
528 public long getUptime(long curTime) {
529 long time = mPastUptime;
530 if (mRunning) {
531 time += curTime - mUptimeStart;
532 }
533 return time;
534 }
535
536 public long getRealtime(long curTime) {
537 long time = mPastRealtime;
538 if (mRunning) {
539 time += curTime - mRealtimeStart;
540 }
541 return time;
542 }
543
544 public long getUptimeStart() {
545 return mUptimeStart;
546 }
547
548 public long getRealtimeStart() {
549 return mRealtimeStart;
550 }
551
552 public boolean isRunning() {
553 return mRunning;
554 }
555
556 public boolean setRunning(boolean running, long uptime, long realtime) {
557 if (mRunning != running) {
558 mRunning = running;
559 if (running) {
560 mUptimeStart = uptime;
561 mRealtimeStart = realtime;
562 long batteryUptime = mUnpluggedUptime = getUptime(uptime);
563 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
564
565 for (int i = mObservers.size() - 1; i >= 0; i--) {
566 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
567 }
568 } else {
569 mPastUptime += uptime - mUptimeStart;
570 mPastRealtime += realtime - mRealtimeStart;
571
572 long batteryUptime = getUptime(uptime);
573 long batteryRealtime = getRealtime(realtime);
574
575 for (int i = mObservers.size() - 1; i >= 0; i--) {
576 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
577 }
578 }
579 return true;
580 }
581 return false;
582 }
583
584 public void readSummaryFromParcel(Parcel in) {
585 mUptime = in.readLong();
586 mRealtime = in.readLong();
587 }
588
589 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
590 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
591 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
592 }
593
594 public void readFromParcel(Parcel in) {
595 mRunning = false;
596 mUptime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800597 mPastUptime = in.readLong();
598 mUptimeStart = in.readLong();
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700599 mRealtime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800600 mPastRealtime = in.readLong();
601 mRealtimeStart = in.readLong();
602 mUnpluggedUptime = in.readLong();
603 mUnpluggedRealtime = in.readLong();
604 }
605
606 public void writeToParcel(Parcel out, long uptime, long realtime) {
607 final long runningUptime = getUptime(uptime);
608 final long runningRealtime = getRealtime(realtime);
609 out.writeLong(mUptime);
610 out.writeLong(runningUptime);
611 out.writeLong(mUptimeStart);
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700612 out.writeLong(mRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800613 out.writeLong(runningRealtime);
614 out.writeLong(mRealtimeStart);
615 out.writeLong(mUnpluggedUptime);
616 out.writeLong(mUnpluggedRealtime);
617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800620 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700621 * State for keeping track of counting information.
622 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800623 public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
Christopher Tate4cee7252010-03-19 14:50:40 -0700624 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800625 final TimeBase mTimeBase;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700626 int mLoadedCount;
627 int mLastCount;
628 int mUnpluggedCount;
629 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700630
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800631 Counter(TimeBase timeBase, Parcel in) {
632 mTimeBase = timeBase;
Christopher Tate4cee7252010-03-19 14:50:40 -0700633 mPluggedCount = in.readInt();
634 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700635 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700636 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700637 mUnpluggedCount = in.readInt();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800638 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700639 }
640
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800641 Counter(TimeBase timeBase) {
642 mTimeBase = timeBase;
643 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700644 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700645
Dianne Hackborn617f8772009-03-31 15:04:46 -0700646 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700647 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700648 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700649 out.writeInt(mUnpluggedCount);
650 }
651
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800652 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700653 mUnpluggedCount = mPluggedCount;
654 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700655 }
656
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800657 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700658 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700659 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700660
Dianne Hackborn617f8772009-03-31 15:04:46 -0700661 /**
662 * Writes a possibly null Counter to a Parcel.
663 *
664 * @param out the Parcel to be written to.
665 * @param counter a Counter, or null.
666 */
667 public static void writeCounterToParcel(Parcel out, Counter counter) {
668 if (counter == null) {
669 out.writeInt(0); // indicates null
670 return;
671 }
672 out.writeInt(1); // indicates non-null
673
674 counter.writeToParcel(out);
675 }
676
677 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700678 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700679 int val = mCount.get();
680 if (which == STATS_SINCE_UNPLUGGED) {
681 val -= mUnpluggedCount;
682 } else if (which != STATS_SINCE_CHARGED) {
683 val -= mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700684 }
685
686 return val;
687 }
688
689 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700690 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700691 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
692 + " mUnpluggedCount=" + mUnpluggedCount
693 + " mPluggedCount=" + mPluggedCount);
694 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700695
Christopher Tate4cee7252010-03-19 14:50:40 -0700696 void stepAtomic() {
697 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700698 }
699
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700700 /**
701 * Clear state of this counter.
702 */
703 void reset(boolean detachIfReset) {
704 mCount.set(0);
705 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
706 if (detachIfReset) {
707 detach();
708 }
709 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700710
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700711 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800712 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700713 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700714
Dianne Hackborn617f8772009-03-31 15:04:46 -0700715 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700716 int count = mCount.get();
717 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700718 }
719
720 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700721 mLoadedCount = in.readInt();
722 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700723 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700724 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700725 }
726 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700727
728 public static class SamplingCounter extends Counter {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800729 SamplingCounter(TimeBase timeBase, Parcel in) {
730 super(timeBase, in);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700731 }
732
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800733 SamplingCounter(TimeBase timeBase) {
734 super(timeBase);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700735 }
736
Christopher Tate4cee7252010-03-19 14:50:40 -0700737 public void addCountAtomic(long count) {
738 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700739 }
740 }
741
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700742 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800743 final TimeBase mTimeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700744 long mCount;
745 long mLoadedCount;
746 long mLastCount;
747 long mUnpluggedCount;
748 long mPluggedCount;
749
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800750 LongSamplingCounter(TimeBase timeBase, Parcel in) {
751 mTimeBase = timeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700752 mPluggedCount = in.readLong();
753 mCount = mPluggedCount;
754 mLoadedCount = in.readLong();
755 mLastCount = 0;
756 mUnpluggedCount = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800757 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700758 }
759
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800760 LongSamplingCounter(TimeBase timeBase) {
761 mTimeBase = timeBase;
762 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700763 }
764
765 public void writeToParcel(Parcel out) {
766 out.writeLong(mCount);
767 out.writeLong(mLoadedCount);
768 out.writeLong(mUnpluggedCount);
769 }
770
771 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800772 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700773 mUnpluggedCount = mPluggedCount;
774 mCount = mPluggedCount;
775 }
776
777 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800778 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700779 mPluggedCount = mCount;
780 }
781
782 public long getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700783 long val = mCount;
784 if (which == STATS_SINCE_UNPLUGGED) {
785 val -= mUnpluggedCount;
786 } else if (which != STATS_SINCE_CHARGED) {
787 val -= mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700788 }
789
790 return val;
791 }
792
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700793 @Override
794 public void logState(Printer pw, String prefix) {
795 pw.println(prefix + "mCount=" + mCount
796 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
797 + " mUnpluggedCount=" + mUnpluggedCount
798 + " mPluggedCount=" + mPluggedCount);
799 }
800
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700801 void addCountLocked(long count) {
802 mCount += count;
803 }
804
805 /**
806 * Clear state of this counter.
807 */
808 void reset(boolean detachIfReset) {
809 mCount = 0;
810 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
811 if (detachIfReset) {
812 detach();
813 }
814 }
815
816 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800817 mTimeBase.remove(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700818 }
819
820 void writeSummaryFromParcelLocked(Parcel out) {
821 out.writeLong(mCount);
822 }
823
824 void readSummaryFromParcelLocked(Parcel in) {
825 mLoadedCount = in.readLong();
826 mCount = mLoadedCount;
827 mLastCount = 0;
828 mUnpluggedCount = mPluggedCount = mLoadedCount;
829 }
830 }
831
Dianne Hackborn617f8772009-03-31 15:04:46 -0700832 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 * State for keeping track of timing information.
834 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800835 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 final int mType;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800837 final TimeBase mTimeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 int mCount;
840 int mLoadedCount;
841 int mLastCount;
842 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 // Times are in microseconds for better accuracy when dividing by the
845 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 /**
848 * The total time we have accumulated since the start of the original
849 * boot, to the last time something interesting happened in the
850 * current run.
851 */
852 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 /**
855 * The total time we loaded for the previous runs. Subtract this from
856 * mTotalTime to find the time for the current run of the system.
857 */
858 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 /**
861 * The run time of the last run of the system, as loaded from the
862 * saved data.
863 */
864 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 /**
867 * The value of mTotalTime when unplug() was last called. Subtract
868 * this from mTotalTime to find the time since the last unplug from
869 * power.
870 */
871 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700872
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700873 /**
874 * Constructs from a parcel.
875 * @param type
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800876 * @param timeBase
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700877 * @param in
878 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800879 Timer(int type, TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800881 mTimeBase = timeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800883 mCount = in.readInt();
884 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700885 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 mUnpluggedCount = in.readInt();
887 mTotalTime = in.readLong();
888 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700889 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 mUnpluggedTime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800891 timeBase.add(this);
Dianne Hackborn29325132014-05-21 15:01:03 -0700892 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 }
894
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800895 Timer(int type, TimeBase timeBase) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800897 mTimeBase = timeBase;
898 timeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 }
Evan Millarc64edde2009-04-18 12:26:32 -0700900
901 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700902
Evan Millarc64edde2009-04-18 12:26:32 -0700903 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700904
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700905 /**
906 * Clear state of this timer. Returns true if the timer is inactive
907 * so can be completely dropped.
908 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800909 boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700910 mTotalTime = mLoadedTime = mLastTime = 0;
911 mCount = mLoadedCount = mLastCount = 0;
912 if (detachIfReset) {
913 detach();
914 }
915 return true;
916 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700917
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700918 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800919 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700920 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700921
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800922 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
Dianne Hackborn29325132014-05-21 15:01:03 -0700923 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
924 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 out.writeInt(mCount);
926 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 out.writeInt(mUnpluggedCount);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800928 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 out.writeLong(mUnpluggedTime);
931 }
932
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800933 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800935 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 + " old mUnpluggedTime=" + mUnpluggedTime
937 + " old mUnpluggedCount=" + mUnpluggedCount);
938 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800939 mUnpluggedTime = computeRunTimeLocked(baseRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 mUnpluggedCount = mCount;
941 if (DEBUG && mType < 0) {
942 Log.v(TAG, "unplug #" + mType
943 + ": new mUnpluggedTime=" + mUnpluggedTime
944 + " new mUnpluggedCount=" + mUnpluggedCount);
945 }
946 }
947
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800948 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700949 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800950 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
Evan Millarc64edde2009-04-18 12:26:32 -0700951 + " old mTotalTime=" + mTotalTime);
952 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800953 mTotalTime = computeRunTimeLocked(baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -0700954 mCount = computeCurrentCountLocked();
955 if (DEBUG && mType < 0) {
956 Log.v(TAG, "plug #" + mType
957 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 }
959 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 /**
962 * Writes a possibly null Timer to a Parcel.
963 *
964 * @param out the Parcel to be written to.
965 * @param timer a Timer, or null.
966 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800967 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 if (timer == null) {
969 out.writeInt(0); // indicates null
970 return;
971 }
972 out.writeInt(1); // indicates non-null
973
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800974 timer.writeToParcel(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 }
976
977 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800978 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700979 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
980 if (which == STATS_SINCE_UNPLUGGED) {
981 val -= mUnpluggedTime;
982 } else if (which != STATS_SINCE_CHARGED) {
983 val -= mLoadedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 }
985
986 return val;
987 }
988
989 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700990 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700991 int val = computeCurrentCountLocked();
992 if (which == STATS_SINCE_UNPLUGGED) {
993 val -= mUnpluggedCount;
994 } else if (which != STATS_SINCE_CHARGED) {
995 val -= mLoadedCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 }
997
998 return val;
999 }
1000
Dianne Hackborn627bba72009-03-24 22:32:56 -07001001 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001002 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
1004 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001005 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001007 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001009 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001010
1011
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001012 void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
1013 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1014 out.writeLong(runTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001015 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -07001016 }
1017
1018 void readSummaryFromParcelLocked(Parcel in) {
1019 // Multiply by 1000 for backwards compatibility
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001020 mTotalTime = mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001021 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001022 mUnpluggedTime = mTotalTime;
1023 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001024 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001025 mUnpluggedCount = mCount;
1026 }
1027 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001028
Evan Millarc64edde2009-04-18 12:26:32 -07001029 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001030
Evan Millarc64edde2009-04-18 12:26:32 -07001031 /**
1032 * The most recent reported count from /proc/wakelocks.
1033 */
1034 int mCurrentReportedCount;
1035
1036 /**
1037 * The reported count from /proc/wakelocks when unplug() was last
1038 * called.
1039 */
1040 int mUnpluggedReportedCount;
1041
1042 /**
1043 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001044 */
Evan Millarc64edde2009-04-18 12:26:32 -07001045 long mCurrentReportedTotalTime;
1046
1047
1048 /**
1049 * The reported total_time from /proc/wakelocks when unplug() was last
1050 * called.
1051 */
1052 long mUnpluggedReportedTotalTime;
1053
1054 /**
1055 * Whether we are currently in a discharge cycle.
1056 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001057 boolean mTimeBaseRunning;
Evan Millarc64edde2009-04-18 12:26:32 -07001058
1059 /**
1060 * Whether we are currently recording reported values.
1061 */
1062 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001063
Evan Millarc64edde2009-04-18 12:26:32 -07001064 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001065 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -07001066 */
1067 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001068
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001069 SamplingTimer(TimeBase timeBase, Parcel in) {
1070 super(0, timeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07001071 mCurrentReportedCount = in.readInt();
1072 mUnpluggedReportedCount = in.readInt();
1073 mCurrentReportedTotalTime = in.readLong();
1074 mUnpluggedReportedTotalTime = in.readLong();
1075 mTrackingReportedValues = in.readInt() == 1;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001076 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001077 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001078
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001079 SamplingTimer(TimeBase timeBase, boolean trackReportedValues) {
1080 super(0, timeBase);
Evan Millarc64edde2009-04-18 12:26:32 -07001081 mTrackingReportedValues = trackReportedValues;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001082 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001083 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001084
Evan Millarc64edde2009-04-18 12:26:32 -07001085 public void setStale() {
1086 mTrackingReportedValues = false;
1087 mUnpluggedReportedTotalTime = 0;
1088 mUnpluggedReportedCount = 0;
1089 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001090
Evan Millarc64edde2009-04-18 12:26:32 -07001091 public void setUpdateVersion(int version) {
1092 mUpdateVersion = version;
1093 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001094
Evan Millarc64edde2009-04-18 12:26:32 -07001095 public int getUpdateVersion() {
1096 return mUpdateVersion;
1097 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001098
Evan Millarc64edde2009-04-18 12:26:32 -07001099 public void updateCurrentReportedCount(int count) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001100 if (mTimeBaseRunning && mUnpluggedReportedCount == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001101 // Updating the reported value for the first time.
1102 mUnpluggedReportedCount = count;
1103 // If we are receiving an update update mTrackingReportedValues;
1104 mTrackingReportedValues = true;
1105 }
1106 mCurrentReportedCount = count;
1107 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001108
Evan Millarc64edde2009-04-18 12:26:32 -07001109 public void updateCurrentReportedTotalTime(long totalTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001110 if (mTimeBaseRunning && mUnpluggedReportedTotalTime == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001111 // Updating the reported value for the first time.
1112 mUnpluggedReportedTotalTime = totalTime;
1113 // If we are receiving an update update mTrackingReportedValues;
1114 mTrackingReportedValues = true;
1115 }
1116 mCurrentReportedTotalTime = totalTime;
1117 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001118
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001119 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1120 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001121 if (mTrackingReportedValues) {
1122 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
1123 mUnpluggedReportedCount = mCurrentReportedCount;
1124 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001125 mTimeBaseRunning = true;
Evan Millarc64edde2009-04-18 12:26:32 -07001126 }
1127
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001128 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1129 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1130 mTimeBaseRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001131 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001132
Evan Millarc64edde2009-04-18 12:26:32 -07001133 public void logState(Printer pw, String prefix) {
1134 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001135 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -07001136 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
1137 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
1138 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
1139 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001140
Evan Millarc64edde2009-04-18 12:26:32 -07001141 protected long computeRunTimeLocked(long curBatteryRealtime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001142 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001143 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
1144 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001145
Evan Millarc64edde2009-04-18 12:26:32 -07001146 protected int computeCurrentCountLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001147 return mCount + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001148 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
1149 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001150
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001151 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1152 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001153 out.writeInt(mCurrentReportedCount);
1154 out.writeInt(mUnpluggedReportedCount);
1155 out.writeLong(mCurrentReportedTotalTime);
1156 out.writeLong(mUnpluggedReportedTotalTime);
1157 out.writeInt(mTrackingReportedValues ? 1 : 0);
1158 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001159
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001160 boolean reset(boolean detachIfReset) {
1161 super.reset(detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001162 setStale();
1163 return true;
1164 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001165
Evan Millarc64edde2009-04-18 12:26:32 -07001166 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
1167 super.writeSummaryFromParcelLocked(out, batteryRealtime);
1168 out.writeLong(mCurrentReportedTotalTime);
1169 out.writeInt(mCurrentReportedCount);
1170 out.writeInt(mTrackingReportedValues ? 1 : 0);
1171 }
1172
1173 void readSummaryFromParcelLocked(Parcel in) {
1174 super.readSummaryFromParcelLocked(in);
1175 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
1176 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
1177 mTrackingReportedValues = in.readInt() == 1;
1178 }
1179 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001180
Evan Millarc64edde2009-04-18 12:26:32 -07001181 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001182 * A timer that increments in batches. It does not run for durations, but just jumps
1183 * for a pre-determined amount.
1184 */
1185 public static final class BatchTimer extends Timer {
1186 final Uid mUid;
1187
1188 /**
1189 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
1190 */
1191 long mLastAddedTime;
1192
1193 /**
1194 * The last duration that we added to the timer. This is in microseconds.
1195 */
1196 long mLastAddedDuration;
1197
1198 /**
1199 * Whether we are currently in a discharge cycle.
1200 */
1201 boolean mInDischarge;
1202
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001203 BatchTimer(Uid uid, int type, TimeBase timeBase, Parcel in) {
1204 super(type, timeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001205 mUid = uid;
1206 mLastAddedTime = in.readLong();
1207 mLastAddedDuration = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001208 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001209 }
1210
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001211 BatchTimer(Uid uid, int type, TimeBase timeBase) {
1212 super(type, timeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001213 mUid = uid;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001214 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001215 }
1216
1217 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001218 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1219 super.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001220 out.writeLong(mLastAddedTime);
1221 out.writeLong(mLastAddedDuration);
1222 }
1223
1224 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001225 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001226 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
1227 mInDischarge = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001228 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001229 }
1230
1231 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001232 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001233 recomputeLastDuration(elapsedRealtime, false);
1234 mInDischarge = true;
1235 // If we are still within the last added duration, then re-added whatever remains.
1236 if (mLastAddedTime == elapsedRealtime) {
1237 mTotalTime += mLastAddedDuration;
1238 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001239 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001240 }
1241
1242 @Override
1243 public void logState(Printer pw, String prefix) {
1244 super.logState(pw, prefix);
1245 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
1246 + " mLastAddedDuration=" + mLastAddedDuration);
1247 }
1248
1249 private long computeOverage(long curTime) {
1250 if (mLastAddedTime > 0) {
1251 return mLastTime + mLastAddedDuration - curTime;
1252 }
1253 return 0;
1254 }
1255
1256 private void recomputeLastDuration(long curTime, boolean abort) {
1257 final long overage = computeOverage(curTime);
1258 if (overage > 0) {
1259 // Aborting before the duration ran out -- roll back the remaining
1260 // duration. Only do this if currently discharging; otherwise we didn't
1261 // actually add the time.
1262 if (mInDischarge) {
1263 mTotalTime -= overage;
1264 }
1265 if (abort) {
1266 mLastAddedTime = 0;
1267 } else {
1268 mLastAddedTime = curTime;
1269 mLastAddedDuration -= overage;
1270 }
1271 }
1272 }
1273
1274 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
1275 final long now = SystemClock.elapsedRealtime() * 1000;
1276 recomputeLastDuration(now, true);
1277 mLastAddedTime = now;
1278 mLastAddedDuration = durationMillis * 1000;
1279 if (mInDischarge) {
1280 mTotalTime += mLastAddedDuration;
1281 mCount++;
1282 }
1283 }
1284
1285 public void abortLastDuration(BatteryStatsImpl stats) {
1286 final long now = SystemClock.elapsedRealtime() * 1000;
1287 recomputeLastDuration(now, true);
1288 }
1289
1290 @Override
1291 protected int computeCurrentCountLocked() {
1292 return mCount;
1293 }
1294
1295 @Override
1296 protected long computeRunTimeLocked(long curBatteryRealtime) {
1297 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000);
1298 if (overage > 0) {
1299 return mTotalTime = overage;
1300 }
1301 return mTotalTime;
1302 }
1303
1304 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001305 boolean reset(boolean detachIfReset) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001306 final long now = SystemClock.elapsedRealtime() * 1000;
1307 recomputeLastDuration(now, true);
1308 boolean stillActive = mLastAddedTime == now;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001309 super.reset(!stillActive && detachIfReset);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001310 return !stillActive;
1311 }
1312 }
1313
1314 /**
Evan Millarc64edde2009-04-18 12:26:32 -07001315 * State for keeping track of timing information.
1316 */
1317 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001318 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07001319 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001320
Evan Millarc64edde2009-04-18 12:26:32 -07001321 int mNesting;
1322
Evan Millarc64edde2009-04-18 12:26:32 -07001323 /**
1324 * The last time at which we updated the timer. If mNesting is > 0,
1325 * subtract this from the current battery time to find the amount of
1326 * time we have been running since we last computed an update.
1327 */
1328 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001329
Evan Millarc64edde2009-04-18 12:26:32 -07001330 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001331 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -07001332 * was actually held for an interesting duration.
1333 */
1334 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001335
Amith Yamasanif37447b2009-10-08 18:28:01 -07001336 long mTimeout;
1337
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001338 /**
1339 * For partial wake locks, keep track of whether we are in the list
1340 * to consume CPU cycles.
1341 */
1342 boolean mInList;
1343
1344 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001345 TimeBase timeBase, Parcel in) {
1346 super(type, timeBase, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001347 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001348 mTimerPool = timerPool;
1349 mUpdateTime = in.readLong();
1350 }
1351
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001352 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001353 TimeBase timeBase) {
1354 super(type, timeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001355 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001356 mTimerPool = timerPool;
1357 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001358
Amith Yamasanif37447b2009-10-08 18:28:01 -07001359 void setTimeout(long timeout) {
1360 mTimeout = timeout;
1361 }
1362
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001363 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1364 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001365 out.writeLong(mUpdateTime);
1366 }
1367
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001368 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001369 if (mNesting > 0) {
1370 if (DEBUG && mType < 0) {
1371 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
1372 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001373 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1374 mUpdateTime = baseRealtime;
Evan Millarc64edde2009-04-18 12:26:32 -07001375 if (DEBUG && mType < 0) {
1376 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
1377 }
1378 }
1379 }
1380
1381 public void logState(Printer pw, String prefix) {
1382 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001383 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384 + " mAcquireTime=" + mAcquireTime);
1385 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001386
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001387 void startRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 if (mNesting++ == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001389 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001390 mUpdateTime = batteryRealtime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 if (mTimerPool != null) {
1392 // Accumulate time to all currently active timers before adding
1393 // this new one to the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001394 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 // Add this timer to the active pool
1396 mTimerPool.add(this);
1397 }
1398 // Increment the count
1399 mCount++;
1400 mAcquireTime = mTotalTime;
1401 if (DEBUG && mType < 0) {
1402 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
1403 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1404 + " mAcquireTime=" + mAcquireTime);
1405 }
1406 }
1407 }
1408
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001409 boolean isRunningLocked() {
1410 return mNesting > 0;
1411 }
1412
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001413 long checkpointRunningLocked(long elapsedRealtimeMs) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001414 if (mNesting > 0) {
1415 // We are running...
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001416 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001417 if (mTimerPool != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001418 return refreshTimersLocked(batteryRealtime, mTimerPool, this);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001419 }
1420 final long heldTime = batteryRealtime - mUpdateTime;
1421 mUpdateTime = batteryRealtime;
1422 mTotalTime += heldTime;
1423 return heldTime;
1424 }
1425 return 0;
1426 }
1427
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001428 long getLastUpdateTimeMs() {
1429 return mUpdateTime;
1430 }
1431
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001432 void stopRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 // Ignore attempt to stop a timer that isn't running
1434 if (mNesting == 0) {
1435 return;
1436 }
1437 if (--mNesting == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001438 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 if (mTimerPool != null) {
1440 // Accumulate time to all active counters, scaled by the total
1441 // active in the pool, before taking this one out of the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001442 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 // Remove this timer from the active pool
1444 mTimerPool.remove(this);
1445 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 mNesting = 1;
1447 mTotalTime = computeRunTimeLocked(batteryRealtime);
1448 mNesting = 0;
1449 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 if (DEBUG && mType < 0) {
1452 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
1453 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1454 + " mAcquireTime=" + mAcquireTime);
1455 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001457 if (mTotalTime == mAcquireTime) {
1458 // If there was no change in the time, then discard this
1459 // count. A somewhat cheezy strategy, but hey.
1460 mCount--;
1461 }
1462 }
1463 }
1464
1465 // Update the total time for all other running Timers with the same type as this Timer
1466 // due to a change in timer count
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001467 private static long refreshTimersLocked(long batteryRealtime,
1468 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001469 long selfTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 final int N = pool.size();
1471 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07001472 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 long heldTime = batteryRealtime - t.mUpdateTime;
1474 if (heldTime > 0) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001475 final long myTime = heldTime / N;
1476 if (t == self) {
1477 selfTime = myTime;
1478 }
1479 t.mTotalTime += myTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 }
1481 t.mUpdateTime = batteryRealtime;
1482 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001483 return selfTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 }
1485
Evan Millarc64edde2009-04-18 12:26:32 -07001486 @Override
1487 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001488 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
1489 curBatteryRealtime = mUpdateTime + mTimeout;
1490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 return mTotalTime + (mNesting > 0
1492 ? (curBatteryRealtime - mUpdateTime)
1493 / (mTimerPool != null ? mTimerPool.size() : 1)
1494 : 0);
1495 }
1496
Evan Millarc64edde2009-04-18 12:26:32 -07001497 @Override
1498 protected int computeCurrentCountLocked() {
1499 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 }
1501
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001502 boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001503 boolean canDetach = mNesting <= 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001504 super.reset(canDetach && detachIfReset);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001505 if (mNesting > 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001506 mUpdateTime = mTimeBase.getRealtime(SystemClock.elapsedRealtime() * 1000);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001507 }
1508 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001509 return canDetach;
1510 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001511
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001512 void detach() {
1513 super.detach();
1514 if (mTimerPool != null) {
1515 mTimerPool.remove(this);
1516 }
1517 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001520 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 mNesting = 0;
1522 }
1523 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001524
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001525 /*
1526 * Get the wakeup reason counter, and create a new one if one
1527 * doesn't already exist.
1528 */
1529 public LongSamplingCounter getWakeupReasonCounterLocked(String name) {
1530 LongSamplingCounter counter = mWakeupReasonStats.get(name);
1531 if (counter == null) {
1532 counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase);
1533 mWakeupReasonStats.put(name, counter);
1534 }
1535 return counter;
1536 }
1537
Evan Millarc64edde2009-04-18 12:26:32 -07001538 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001539
Todd Poynor73f534a2012-06-19 11:07:26 -07001540 FileInputStream is;
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001541 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -07001542 int len;
Todd Poynor73f534a2012-06-19 11:07:26 -07001543 boolean wakeup_sources = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001544
Evan Millarc64edde2009-04-18 12:26:32 -07001545 try {
Todd Poynor73f534a2012-06-19 11:07:26 -07001546 try {
1547 is = new FileInputStream("/proc/wakelocks");
1548 } catch (java.io.FileNotFoundException e) {
1549 try {
1550 is = new FileInputStream("/d/wakeup_sources");
1551 wakeup_sources = true;
1552 } catch (java.io.FileNotFoundException e2) {
1553 return null;
Evan Millarc64edde2009-04-18 12:26:32 -07001554 }
1555 }
Todd Poynor73f534a2012-06-19 11:07:26 -07001556
1557 len = is.read(buffer);
1558 is.close();
Evan Millarc64edde2009-04-18 12:26:32 -07001559 } catch (java.io.IOException e) {
1560 return null;
1561 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001562
Todd Poynor73f534a2012-06-19 11:07:26 -07001563 if (len > 0) {
1564 int i;
1565 for (i=0; i<len; i++) {
1566 if (buffer[i] == '\0') {
1567 len = i;
1568 break;
1569 }
1570 }
1571 }
1572
1573 return parseProcWakelocks(buffer, len, wakeup_sources);
Evan Millarc64edde2009-04-18 12:26:32 -07001574 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001575
Evan Millarc64edde2009-04-18 12:26:32 -07001576 private final Map<String, KernelWakelockStats> parseProcWakelocks(
Todd Poynor73f534a2012-06-19 11:07:26 -07001577 byte[] wlBuffer, int len, boolean wakeup_sources) {
Evan Millarc64edde2009-04-18 12:26:32 -07001578 String name;
1579 int count;
1580 long totalTime;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001581 int startIndex;
1582 int endIndex;
Evan Millarc64edde2009-04-18 12:26:32 -07001583 int numUpdatedWlNames = 0;
1584
1585 // Advance past the first line.
1586 int i;
1587 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1588 startIndex = endIndex = i + 1;
1589
1590 synchronized(this) {
1591 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001592
Evan Millarc64edde2009-04-18 12:26:32 -07001593 sKernelWakelockUpdateVersion++;
1594 while (endIndex < len) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001595 for (endIndex=startIndex;
1596 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
Evan Millarc64edde2009-04-18 12:26:32 -07001597 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001598 endIndex++; // endIndex is an exclusive upper bound.
1599 // Don't go over the end of the buffer, Process.parseProcLine might
1600 // write to wlBuffer[endIndex]
1601 if (endIndex >= (len - 1) ) {
1602 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -07001603 }
Evan Millarc64edde2009-04-18 12:26:32 -07001604
1605 String[] nameStringArray = mProcWakelocksName;
1606 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001607 // Stomp out any bad characters since this is from a circular buffer
1608 // A corruption is seen sometimes that results in the vm crashing
1609 // This should prevent crashes and the line will probably fail to parse
1610 for (int j = startIndex; j < endIndex; j++) {
1611 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1612 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001613 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
Todd Poynor73f534a2012-06-19 11:07:26 -07001614 wakeup_sources ? WAKEUP_SOURCES_FORMAT :
1615 PROC_WAKELOCKS_FORMAT,
1616 nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001617
Evan Millarc64edde2009-04-18 12:26:32 -07001618 name = nameStringArray[0];
1619 count = (int) wlData[1];
Todd Poynor73f534a2012-06-19 11:07:26 -07001620
1621 if (wakeup_sources) {
1622 // convert milliseconds to microseconds
1623 totalTime = wlData[2] * 1000;
1624 } else {
1625 // convert nanoseconds to microseconds with rounding.
1626 totalTime = (wlData[2] + 500) / 1000;
1627 }
Evan Millarc64edde2009-04-18 12:26:32 -07001628
Amith Yamasani53b707b2009-09-30 11:05:30 -07001629 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001630 if (!m.containsKey(name)) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001631 m.put(name, new KernelWakelockStats(count, totalTime,
Evan Millarc64edde2009-04-18 12:26:32 -07001632 sKernelWakelockUpdateVersion));
1633 numUpdatedWlNames++;
1634 } else {
1635 KernelWakelockStats kwlStats = m.get(name);
1636 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1637 kwlStats.mCount += count;
1638 kwlStats.mTotalTime += totalTime;
1639 } else {
1640 kwlStats.mCount = count;
1641 kwlStats.mTotalTime = totalTime;
1642 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1643 numUpdatedWlNames++;
1644 }
1645 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001646 }
Evan Millarc64edde2009-04-18 12:26:32 -07001647 startIndex = endIndex;
1648 }
1649
1650 if (m.size() != numUpdatedWlNames) {
1651 // Don't report old data.
1652 Iterator<KernelWakelockStats> itr = m.values().iterator();
1653 while (itr.hasNext()) {
1654 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1655 itr.remove();
1656 }
1657 }
1658 }
1659 return m;
1660 }
1661 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001662
Evan Millarc64edde2009-04-18 12:26:32 -07001663 private class KernelWakelockStats {
1664 public int mCount;
1665 public long mTotalTime;
1666 public int mVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001667
Evan Millarc64edde2009-04-18 12:26:32 -07001668 KernelWakelockStats(int count, long totalTime, int version) {
1669 mCount = count;
1670 mTotalTime = totalTime;
1671 mVersion = version;
1672 }
1673 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001674
Evan Millarc64edde2009-04-18 12:26:32 -07001675 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001676 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001677 * doesn't already exist.
1678 */
1679 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1680 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1681 if (kwlt == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001682 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, true /* track reported values */);
Evan Millarc64edde2009-04-18 12:26:32 -07001683 mKernelWakelockStats.put(name, kwlt);
1684 }
1685 return kwlt;
1686 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001687
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001688 private int getCurrentBluetoothPingCount() {
1689 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001690 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1691 if (deviceList.size() > 0) {
1692 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001693 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001694 }
1695 return -1;
1696 }
1697
1698 public int getBluetoothPingCount() {
1699 if (mBluetoothPingStart == -1) {
1700 return mBluetoothPingCount;
1701 } else if (mBtHeadset != null) {
1702 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1703 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001704 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001705 }
1706
1707 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001708 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1709 mBluetoothPingStart = getCurrentBluetoothPingCount();
1710 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001711 mBtHeadset = headset;
1712 }
1713
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001714 private int writeHistoryTag(HistoryTag tag) {
1715 Integer idxObj = mHistoryTagPool.get(tag);
1716 int idx;
1717 if (idxObj != null) {
1718 idx = idxObj;
1719 } else {
1720 idx = mNextHistoryTagIdx;
1721 HistoryTag key = new HistoryTag();
1722 key.setTo(tag);
1723 tag.poolIdx = idx;
1724 mHistoryTagPool.put(key, idx);
1725 mNextHistoryTagIdx++;
1726 mNumHistoryTagChars += key.string.length() + 1;
1727 }
1728 return idx;
1729 }
1730
1731 private void readHistoryTag(int index, HistoryTag tag) {
1732 tag.string = mReadHistoryStrings[index];
1733 tag.uid = mReadHistoryUids[index];
1734 tag.poolIdx = index;
1735 }
1736
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001737 // Part of initial delta int that specifies the time delta.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001738 static final int DELTA_TIME_MASK = 0x7ffff;
1739 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
1740 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
1741 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001742 // Flag in delta int: a new battery level int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001743 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001744 // Flag in delta int: a new full state and battery status int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001745 static final int DELTA_STATE_FLAG = 0x00100000;
1746 // Flag in delta int: a new full state2 int follows.
1747 static final int DELTA_STATE2_FLAG = 0x00200000;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001748 // Flag in delta int: contains a wakelock or wakeReason tag.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001749 static final int DELTA_WAKELOCK_FLAG = 0x00400000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001750 // Flag in delta int: contains an event description.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001751 static final int DELTA_EVENT_FLAG = 0x00800000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001752 // These upper bits are the frequently changing state bits.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001753 static final int DELTA_STATE_MASK = 0xff000000;
1754
1755 // These are the pieces of battery state that are packed in to the upper bits of
1756 // the state int that have been packed in to the first delta int. They must fit
1757 // in DELTA_STATE_MASK.
1758 static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
1759 static final int STATE_BATTERY_STATUS_SHIFT = 29;
1760 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
1761 static final int STATE_BATTERY_HEALTH_SHIFT = 26;
1762 static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
1763 static final int STATE_BATTERY_PLUG_SHIFT = 24;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001764
1765 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001766 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001767 dest.writeInt(DELTA_TIME_ABS);
1768 cur.writeToParcel(dest, 0);
1769 return;
1770 }
1771
1772 final long deltaTime = cur.time - last.time;
1773 final int lastBatteryLevelInt = buildBatteryLevelInt(last);
1774 final int lastStateInt = buildStateInt(last);
1775
1776 int deltaTimeToken;
1777 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
1778 deltaTimeToken = DELTA_TIME_LONG;
1779 } else if (deltaTime >= DELTA_TIME_ABS) {
1780 deltaTimeToken = DELTA_TIME_INT;
1781 } else {
1782 deltaTimeToken = (int)deltaTime;
1783 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001784 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001785 final int batteryLevelInt = buildBatteryLevelInt(cur);
1786 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
1787 if (batteryLevelIntChanged) {
1788 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
1789 }
1790 final int stateInt = buildStateInt(cur);
1791 final boolean stateIntChanged = stateInt != lastStateInt;
1792 if (stateIntChanged) {
1793 firstToken |= DELTA_STATE_FLAG;
1794 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001795 final boolean state2IntChanged = cur.states2 != last.states2;
1796 if (state2IntChanged) {
1797 firstToken |= DELTA_STATE2_FLAG;
1798 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001799 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001800 firstToken |= DELTA_WAKELOCK_FLAG;
1801 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001802 if (cur.eventCode != HistoryItem.EVENT_NONE) {
1803 firstToken |= DELTA_EVENT_FLAG;
1804 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001805 dest.writeInt(firstToken);
1806 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
1807 + " deltaTime=" + deltaTime);
1808
1809 if (deltaTimeToken >= DELTA_TIME_INT) {
1810 if (deltaTimeToken == DELTA_TIME_INT) {
1811 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
1812 dest.writeInt((int)deltaTime);
1813 } else {
1814 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
1815 dest.writeLong(deltaTime);
1816 }
1817 }
1818 if (batteryLevelIntChanged) {
1819 dest.writeInt(batteryLevelInt);
1820 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
1821 + Integer.toHexString(batteryLevelInt)
1822 + " batteryLevel=" + cur.batteryLevel
1823 + " batteryTemp=" + cur.batteryTemperature
1824 + " batteryVolt=" + (int)cur.batteryVoltage);
1825 }
1826 if (stateIntChanged) {
1827 dest.writeInt(stateInt);
1828 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
1829 + Integer.toHexString(stateInt)
1830 + " batteryStatus=" + cur.batteryStatus
1831 + " batteryHealth=" + cur.batteryHealth
1832 + " batteryPlugType=" + cur.batteryPlugType
1833 + " states=0x" + Integer.toHexString(cur.states));
1834 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001835 if (state2IntChanged) {
1836 dest.writeInt(cur.states2);
1837 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
1838 + Integer.toHexString(cur.states2));
1839 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001840 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
1841 int wakeLockIndex;
1842 int wakeReasonIndex;
1843 if (cur.wakelockTag != null) {
1844 wakeLockIndex = writeHistoryTag(cur.wakelockTag);
1845 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
1846 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
1847 } else {
1848 wakeLockIndex = 0xffff;
1849 }
1850 if (cur.wakeReasonTag != null) {
1851 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
1852 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
1853 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
1854 } else {
1855 wakeReasonIndex = 0xffff;
1856 }
1857 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001858 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001859 if (cur.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001860 int index = writeHistoryTag(cur.eventTag);
1861 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
Dianne Hackborn099bc622014-01-22 13:39:16 -08001862 dest.writeInt(codeAndIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001863 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
1864 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
1865 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001866 }
1867 }
1868
1869 private int buildBatteryLevelInt(HistoryItem h) {
1870 return ((((int)h.batteryLevel)<<25)&0xfe000000)
1871 | ((((int)h.batteryTemperature)<<14)&0x01ffc000)
1872 | (((int)h.batteryVoltage)&0x00003fff);
1873 }
1874
1875 private int buildStateInt(HistoryItem h) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001876 int plugType = 0;
1877 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
1878 plugType = 1;
1879 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
1880 plugType = 2;
1881 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
1882 plugType = 3;
1883 }
1884 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
1885 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
1886 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001887 | (h.states&(~DELTA_STATE_MASK));
1888 }
1889
1890 public void readHistoryDelta(Parcel src, HistoryItem cur) {
1891 int firstToken = src.readInt();
1892 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001893 cur.cmd = HistoryItem.CMD_UPDATE;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001894 cur.numReadInts = 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001895 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
1896 + " deltaTimeToken=" + deltaTimeToken);
1897
1898 if (deltaTimeToken < DELTA_TIME_ABS) {
1899 cur.time += deltaTimeToken;
1900 } else if (deltaTimeToken == DELTA_TIME_ABS) {
1901 cur.time = src.readLong();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001902 cur.numReadInts += 2;
1903 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001904 cur.readFromParcel(src);
1905 return;
1906 } else if (deltaTimeToken == DELTA_TIME_INT) {
1907 int delta = src.readInt();
1908 cur.time += delta;
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: time delta=" + delta + " new time=" + cur.time);
1911 } else {
1912 long delta = src.readLong();
1913 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
1914 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001915 cur.numReadInts += 2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001916 }
1917
1918 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
1919 int batteryLevelInt = src.readInt();
1920 cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
1921 cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21);
1922 cur.batteryVoltage = (char)(batteryLevelInt&0x3fff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001923 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001924 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
1925 + Integer.toHexString(batteryLevelInt)
1926 + " batteryLevel=" + cur.batteryLevel
1927 + " batteryTemp=" + cur.batteryTemperature
1928 + " batteryVolt=" + (int)cur.batteryVoltage);
1929 }
1930
1931 if ((firstToken&DELTA_STATE_FLAG) != 0) {
1932 int stateInt = src.readInt();
1933 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001934 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
1935 & STATE_BATTERY_STATUS_MASK);
1936 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
1937 & STATE_BATTERY_HEALTH_MASK);
1938 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
1939 & STATE_BATTERY_PLUG_MASK);
1940 switch (cur.batteryPlugType) {
1941 case 1:
1942 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
1943 break;
1944 case 2:
1945 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
1946 break;
1947 case 3:
1948 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
1949 break;
1950 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001951 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001952 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
1953 + Integer.toHexString(stateInt)
1954 + " batteryStatus=" + cur.batteryStatus
1955 + " batteryHealth=" + cur.batteryHealth
1956 + " batteryPlugType=" + cur.batteryPlugType
1957 + " states=0x" + Integer.toHexString(cur.states));
1958 } else {
1959 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK));
1960 }
1961
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001962 if ((firstToken&DELTA_STATE2_FLAG) != 0) {
1963 cur.states2 = src.readInt();
1964 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
1965 + Integer.toHexString(cur.states2));
1966 }
1967
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001968 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001969 int indexes = src.readInt();
1970 int wakeLockIndex = indexes&0xffff;
1971 int wakeReasonIndex = (indexes>>16)&0xffff;
1972 if (wakeLockIndex != 0xffff) {
1973 cur.wakelockTag = cur.localWakelockTag;
1974 readHistoryTag(wakeLockIndex, cur.wakelockTag);
1975 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
1976 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
1977 } else {
1978 cur.wakelockTag = null;
1979 }
1980 if (wakeReasonIndex != 0xffff) {
1981 cur.wakeReasonTag = cur.localWakeReasonTag;
1982 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
1983 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
1984 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
1985 } else {
1986 cur.wakeReasonTag = null;
1987 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001988 cur.numReadInts += 1;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001989 } else {
1990 cur.wakelockTag = null;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001991 cur.wakeReasonTag = null;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001992 }
1993
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001994 if ((firstToken&DELTA_EVENT_FLAG) != 0) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001995 cur.eventTag = cur.localEventTag;
1996 final int codeAndIndex = src.readInt();
Dianne Hackborn099bc622014-01-22 13:39:16 -08001997 cur.eventCode = (codeAndIndex&0xffff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001998 final int index = ((codeAndIndex>>16)&0xffff);
1999 readHistoryTag(index, cur.eventTag);
2000 cur.numReadInts += 1;
2001 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
2002 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
2003 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002004 } else {
2005 cur.eventCode = HistoryItem.EVENT_NONE;
2006 }
2007 }
2008
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002009 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002010 if (!mHaveBatteryLevel || !mRecordingHistory) {
2011 return;
2012 }
2013
Dianne Hackborn40c87252014-03-19 16:55:40 -07002014 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002015 final int diffStates = mHistoryLastWritten.states^cur.states;
2016 final int diffStates2 = mHistoryLastWritten.states2^cur.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002017 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002018 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002019 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
2020 + Integer.toHexString(diffStates) + " lastDiff="
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002021 + Integer.toHexString(lastDiffStates) + " diff2="
2022 + Integer.toHexString(diffStates2) + " lastDiff2="
2023 + Integer.toHexString(lastDiffStates2));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002024 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002025 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002026 && (diffStates2&lastDiffStates2) == 0
2027 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
2028 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002029 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002030 || cur.eventCode == HistoryItem.EVENT_NONE)
2031 && mHistoryLastWritten.batteryLevel == cur.batteryLevel
2032 && mHistoryLastWritten.batteryStatus == cur.batteryStatus
2033 && mHistoryLastWritten.batteryHealth == cur.batteryHealth
2034 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
2035 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
2036 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002037 // We can merge this new change in with the last one. Merging is
Dianne Hackborn40c87252014-03-19 16:55:40 -07002038 // allowed as long as only the states have changed, and within those states
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002039 // as long as no bit has changed both between now and the last entry, as
2040 // well as the last entry and the one before it (so we capture any toggles).
2041 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002042 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
2043 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
2044 mHistoryBufferLastPos = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002045 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002046 // If the last written history had a wakelock tag, we need to retain it.
2047 // Note that the condition above made sure that we aren't in a case where
2048 // both it and the current history item have a wakelock tag.
2049 if (mHistoryLastWritten.wakelockTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002050 cur.wakelockTag = cur.localWakelockTag;
2051 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002052 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002053 // If the last written history had a wake reason tag, we need to retain it.
2054 // Note that the condition above made sure that we aren't in a case where
2055 // both it and the current history item have a wakelock tag.
2056 if (mHistoryLastWritten.wakeReasonTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002057 cur.wakeReasonTag = cur.localWakeReasonTag;
2058 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002059 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002060 // If the last written history had an event, we need to retain it.
2061 // Note that the condition above made sure that we aren't in a case where
2062 // both it and the current history item have an event.
2063 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002064 cur.eventCode = mHistoryLastWritten.eventCode;
2065 cur.eventTag = cur.localEventTag;
2066 cur.eventTag.setTo(mHistoryLastWritten.eventTag);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002067 }
Dianne Hackborn1fadab52011-04-14 17:57:33 -07002068 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002069 }
2070
2071 final int dataSize = mHistoryBuffer.dataSize();
2072 if (dataSize >= MAX_HISTORY_BUFFER) {
2073 if (!mHistoryOverflow) {
2074 mHistoryOverflow = true;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002075 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
2076 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002077 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002078 }
2079
2080 // Once we've reached the maximum number of items, we only
2081 // record changes to the battery level and the most interesting states.
2082 // Once we've reached the maximum maximum number of items, we only
2083 // record changes to the battery level.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002084 if (mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002085 (dataSize >= MAX_MAX_HISTORY_BUFFER
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002086 || ((mHistoryLastWritten.states^cur.states)
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002087 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
2088 return;
2089 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002090
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002091 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002092 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002093 }
2094
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002095 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002096 }
2097
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002098 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
2099 HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002100 if (mIteratingHistory) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002101 throw new IllegalStateException("Can't do this while iterating history!");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002102 }
2103 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
2104 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002105 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002106 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07002107 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002108 cur.wakelockTag = null;
2109 cur.wakeReasonTag = null;
2110 cur.eventCode = HistoryItem.EVENT_NONE;
2111 cur.eventTag = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002112 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
2113 + " now " + mHistoryBuffer.dataPosition()
2114 + " size is now " + mHistoryBuffer.dataSize());
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002115 }
2116
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002117 int mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002118 int mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002119
Dianne Hackborn40c87252014-03-19 16:55:40 -07002120 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002121 if (mTrackRunningHistoryElapsedRealtime != 0) {
2122 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
2123 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
2124 if (diffUptime < (diffElapsed-20)) {
2125 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
2126 mHistoryAddTmp.setTo(mHistoryLastWritten);
2127 mHistoryAddTmp.wakelockTag = null;
2128 mHistoryAddTmp.wakeReasonTag = null;
2129 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
2130 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
2131 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
2132 }
2133 }
2134 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
2135 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
2136 mTrackRunningHistoryUptime = uptimeMs;
2137 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
2138 }
2139
2140 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
2141 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002142
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002143 if (!USE_OLD_HISTORY) {
2144 return;
2145 }
2146
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002147 if (!mHaveBatteryLevel || !mRecordingHistory) {
2148 return;
2149 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002150
2151 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002152 // and no states have since the last recorded entry changed and
2153 // are now resetting back to their original value, then just collapse
2154 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002155 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002156 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002157 && ((mHistoryEnd.states^cur.states)&mChangedStates) == 0
2158 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002159 // If the current is the same as the one before, then we no
2160 // longer need the entry.
2161 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002162 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002163 && mHistoryLastEnd.sameNonEvent(cur)) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002164 mHistoryLastEnd.next = null;
2165 mHistoryEnd.next = mHistoryCache;
2166 mHistoryCache = mHistoryEnd;
2167 mHistoryEnd = mHistoryLastEnd;
2168 mHistoryLastEnd = null;
2169 } else {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002170 mChangedStates |= mHistoryEnd.states^cur.states;
2171 mChangedStates2 |= mHistoryEnd.states^cur.states2;
2172 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002173 }
2174 return;
2175 }
2176
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002177 mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002178 mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002179
2180 if (mNumHistoryItems == MAX_HISTORY_ITEMS
2181 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002182 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002183 }
2184
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002185 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
2186 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002187 // record changes to the battery level and the most interesting states.
2188 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002189 // record changes to the battery level.
2190 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002191 == cur.batteryLevel &&
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002192 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002193 || ((mHistoryEnd.states^cur.states)
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002194 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002195 return;
2196 }
2197 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002198
Dianne Hackborn40c87252014-03-19 16:55:40 -07002199 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002200 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002201
Dianne Hackborn40c87252014-03-19 16:55:40 -07002202 void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
2203 String name, int uid) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002204 mHistoryCur.eventCode = code;
2205 mHistoryCur.eventTag = mHistoryCur.localEventTag;
2206 mHistoryCur.eventTag.string = name;
2207 mHistoryCur.eventTag.uid = uid;
Dianne Hackborn4590e522014-03-24 13:36:46 -07002208 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002209 }
2210
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002211 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002212 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002213 if (rec != null) {
2214 mHistoryCache = rec.next;
2215 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002216 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002217 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002218 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002219
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002220 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002221 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002222
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002223 void addHistoryRecordLocked(HistoryItem rec) {
2224 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002225 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002226 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002227 if (mHistoryEnd != null) {
2228 mHistoryEnd.next = rec;
2229 mHistoryEnd = rec;
2230 } else {
2231 mHistory = mHistoryEnd = rec;
2232 }
2233 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002234
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002235 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002236 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002237 if (USE_OLD_HISTORY) {
2238 if (mHistory != null) {
2239 mHistoryEnd.next = mHistoryCache;
2240 mHistoryCache = mHistory;
2241 mHistory = mHistoryLastEnd = mHistoryEnd = null;
2242 }
2243 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002244 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002245
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002246 mHistoryBaseTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002247 mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002248 mTrackRunningHistoryElapsedRealtime = 0;
2249 mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002250
2251 mHistoryBuffer.setDataSize(0);
2252 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002253 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002254 mHistoryLastLastWritten.clear();
2255 mHistoryLastWritten.clear();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002256 mHistoryTagPool.clear();
2257 mNextHistoryTagIdx = 0;
2258 mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002259 mHistoryBufferLastPos = -1;
2260 mHistoryOverflow = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002261 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002262
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002263 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
2264 long realtime) {
2265 if (mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime)) {
2266 if (unplugged) {
2267 // Track bt headset ping count
2268 mBluetoothPingStart = getCurrentBluetoothPingCount();
2269 mBluetoothPingCount = 0;
2270 } else {
2271 // Track bt headset ping count
2272 mBluetoothPingCount = getBluetoothPingCount();
2273 mBluetoothPingStart = -1;
2274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002276
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002277 boolean unpluggedScreenOff = unplugged && screenOff;
2278 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
2279 updateKernelWakelocksLocked();
2280 requestWakelockCpuUpdate();
2281 if (!unpluggedScreenOff) {
2282 // We are switching to no longer tracking wake locks, but we want
2283 // the next CPU update we receive to take them in to account.
2284 mDistributeWakelockCpu = true;
2285 }
2286 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002287 }
2288 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002289
Dianne Hackborn099bc622014-01-22 13:39:16 -08002290 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
2291 mIsolatedUids.put(isolatedUid, appUid);
2292 }
2293
2294 public void removeIsolatedUidLocked(int isolatedUid, int appUid) {
2295 int curUid = mIsolatedUids.get(isolatedUid, -1);
2296 if (curUid == appUid) {
2297 mIsolatedUids.delete(isolatedUid);
2298 }
2299 }
2300
2301 public int mapUid(int uid) {
2302 int isolated = mIsolatedUids.get(uid, -1);
2303 return isolated > 0 ? isolated : uid;
2304 }
2305
2306 public void noteEventLocked(int code, String name, int uid) {
2307 uid = mapUid(uid);
Dianne Hackborn37de0982014-05-09 09:32:18 -07002308 if (!mActiveEvents.updateState(code, name, uid, 0)) {
2309 return;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002310 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07002311 final long elapsedRealtime = SystemClock.elapsedRealtime();
2312 final long uptime = SystemClock.uptimeMillis();
2313 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002314 }
2315
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002316 private void requestWakelockCpuUpdate() {
2317 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
2318 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
2319 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
2320 }
2321 }
2322
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002323 public void setRecordAllWakeLocksLocked(boolean enabled) {
2324 mRecordAllWakeLocks = enabled;
2325 if (!enabled) {
2326 // Clear out any existing state.
2327 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK);
2328 }
2329 }
2330
Dianne Hackborn9a755432014-05-15 17:05:22 -07002331 public void setNoAutoReset(boolean enabled) {
2332 mNoAutoReset = enabled;
2333 }
2334
2335 private String mInitialAcquireWakeName;
2336 private int mInitialAcquireWakeUid = -1;
2337
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002338 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002339 boolean unimportantForLogging, long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002340 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002341 if (type == WAKE_TYPE_PARTIAL) {
2342 // Only care about partial wake locks, since full wake locks
2343 // will be canceled when the user puts the screen to sleep.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002344 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002345 if (mRecordAllWakeLocks) {
2346 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, name, uid, 0)) {
2347 addHistoryEventLocked(elapsedRealtime, uptime,
2348 HistoryItem.EVENT_WAKE_LOCK_START, name, uid);
2349 }
2350 }
2351 historyName = historyName == null ? name : historyName;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002352 if (mWakeLockNesting == 0) {
2353 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
2354 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
2355 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002356 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002357 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002358 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002359 mWakeLockImportant = !unimportantForLogging;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002360 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002361 } else if (!mWakeLockImportant && !unimportantForLogging) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002362 if (mHistoryLastWritten.wakelockTag != null) {
2363 // We'll try to update the last tag.
2364 mHistoryLastWritten.wakelockTag = null;
2365 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002366 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002367 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002368 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002369 }
2370 mWakeLockImportant = true;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002371 }
2372 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002373 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002374 if (uid >= 0) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002375 //if (uid == 0) {
2376 // Slog.wtf(TAG, "Acquiring wake lock from root: " + name);
2377 //}
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002378 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002379 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002380 }
2381 }
2382
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002383 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type,
2384 long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002385 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002386 if (type == WAKE_TYPE_PARTIAL) {
2387 mWakeLockNesting--;
Dianne Hackborn536456f2014-05-23 16:51:05 -07002388 if (mRecordAllWakeLocks) {
2389 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, name, uid, 0)) {
2390 addHistoryEventLocked(elapsedRealtime, uptime,
2391 HistoryItem.EVENT_WAKE_LOCK_FINISH, name, uid);
2392 }
2393 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002394 if (mWakeLockNesting == 0) {
2395 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
2396 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
2397 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn37de0982014-05-09 09:32:18 -07002398 mInitialAcquireWakeName = null;
2399 mInitialAcquireWakeUid = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002400 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002401 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002402 }
2403 if (uid >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002404 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002405 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002406 }
2407 }
2408
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002409 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
2410 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002411 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002412 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002413 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002414 for (int i=0; i<N; i++) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002415 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002416 elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002417 }
2418 }
2419
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002420 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
2421 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002422 String newHistoryName, int newType, boolean newUnimportantForLogging) {
2423 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002424 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002425 // For correct semantics, we start the need worksources first, so that we won't
2426 // make inappropriate history items as if all wake locks went away and new ones
2427 // appeared. This is okay because tracking of wake locks allows nesting.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002428 final int NN = newWs.size();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002429 for (int i=0; i<NN; i++) {
2430 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002431 newUnimportantForLogging, elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002432 }
2433 final int NO = ws.size();
2434 for (int i=0; i<NO; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002435 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002436 }
2437 }
2438
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002439 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
2440 String historyName, int type) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002441 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002442 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002443 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002444 for (int i=0; i<N; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002445 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002446 }
2447 }
2448
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002449 void aggregateLastWakeupUptimeLocked(long uptimeMs) {
2450 if (mLastWakeupReason != null) {
2451 long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
2452 LongSamplingCounter timer = getWakeupReasonCounterLocked(mLastWakeupReason);
2453 timer.addCountLocked(deltaUptime);
2454 mLastWakeupReason = null;
2455 }
2456 }
2457
2458 public void noteWakeupReasonLocked(String reason) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002459 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002460 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002461 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason reason \"" + reason +"\": "
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002462 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002463 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002464 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
2465 mHistoryCur.wakeReasonTag.string = reason;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002466 mHistoryCur.wakeReasonTag.uid = 0;
2467 mLastWakeupReason = reason;
2468 mLastWakeupUptimeMs = uptime;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002469 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002470 }
2471
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002472 public int startAddingCpuLocked() {
2473 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2474
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002475 final int N = mPartialTimers.size();
2476 if (N == 0) {
2477 mLastPartialTimers.clear();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002478 mDistributeWakelockCpu = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002479 return 0;
2480 }
2481
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002482 if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) {
2483 return 0;
2484 }
2485
2486 mDistributeWakelockCpu = false;
2487
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002488 // How many timers should consume CPU? Only want to include ones
2489 // that have already been in the list.
2490 for (int i=0; i<N; i++) {
2491 StopwatchTimer st = mPartialTimers.get(i);
2492 if (st.mInList) {
2493 Uid uid = st.mUid;
2494 // We don't include the system UID, because it so often
2495 // holds wake locks at one request or another of an app.
2496 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2497 return 50;
2498 }
2499 }
2500 }
2501
2502 return 0;
2503 }
2504
2505 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
2506 final int N = mPartialTimers.size();
2507 if (perc != 0) {
2508 int num = 0;
2509 for (int i=0; i<N; i++) {
2510 StopwatchTimer st = mPartialTimers.get(i);
2511 if (st.mInList) {
2512 Uid uid = st.mUid;
2513 // We don't include the system UID, because it so often
2514 // holds wake locks at one request or another of an app.
2515 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2516 num++;
2517 }
2518 }
2519 }
2520 if (num != 0) {
2521 for (int i=0; i<N; i++) {
2522 StopwatchTimer st = mPartialTimers.get(i);
2523 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002524 Uid uid = st.mUid;
2525 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07002526 int myUTime = utime/num;
2527 int mySTime = stime/num;
2528 utime -= myUTime;
2529 stime -= mySTime;
2530 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002531 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
2532 proc.addCpuTimeLocked(myUTime, mySTime);
2533 proc.addSpeedStepTimes(cpuSpeedTimes);
2534 }
2535 }
2536 }
2537 }
2538
2539 // Just in case, collect any lost CPU time.
2540 if (utime != 0 || stime != 0) {
2541 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
2542 if (uid != null) {
2543 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
2544 proc.addCpuTimeLocked(utime, stime);
2545 proc.addSpeedStepTimes(cpuSpeedTimes);
2546 }
2547 }
2548 }
2549
2550 final int NL = mLastPartialTimers.size();
2551 boolean diff = N != NL;
2552 for (int i=0; i<NL && !diff; i++) {
2553 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
2554 }
2555 if (!diff) {
2556 for (int i=0; i<NL; i++) {
2557 mPartialTimers.get(i).mInList = true;
2558 }
2559 return;
2560 }
2561
2562 for (int i=0; i<NL; i++) {
2563 mLastPartialTimers.get(i).mInList = false;
2564 }
2565 mLastPartialTimers.clear();
2566 for (int i=0; i<N; i++) {
2567 StopwatchTimer st = mPartialTimers.get(i);
2568 st.mInList = true;
2569 mLastPartialTimers.add(st);
2570 }
2571 }
2572
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002573 public void noteProcessDiedLocked(int uid, int pid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002574 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002575 Uid u = mUidStats.get(uid);
2576 if (u != null) {
2577 u.mPids.remove(pid);
2578 }
2579 }
2580
2581 public long getProcessWakeTime(int uid, int pid, long realtime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002582 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002583 Uid u = mUidStats.get(uid);
2584 if (u != null) {
2585 Uid.Pid p = u.mPids.get(pid);
2586 if (p != null) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002587 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002588 }
2589 }
2590 return 0;
2591 }
2592
2593 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002594 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002595 Uid u = mUidStats.get(uid);
2596 if (u != null) {
2597 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
2598 }
2599 }
2600
Dianne Hackborn287952c2010-09-22 22:34:31 -07002601 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002602 uid = mapUid(uid);
Dianne Hackborn287952c2010-09-22 22:34:31 -07002603 Uid u = mUidStats.get(uid);
2604 if (u != null) {
2605 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
2606 }
2607 }
2608
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002609 int mSensorNesting;
2610
2611 public void noteStartSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002612 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002613 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002614 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002615 if (mSensorNesting == 0) {
2616 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
2617 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
2618 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002619 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002620 }
2621 mSensorNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002622 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002623 }
2624
2625 public void noteStopSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002626 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002627 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002628 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002629 mSensorNesting--;
2630 if (mSensorNesting == 0) {
2631 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
2632 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
2633 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002634 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002635 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002636 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002637 }
2638
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002639 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002640
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002641 public void noteStartGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002642 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002643 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002644 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002645 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002646 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002647 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
2648 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002649 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002650 }
2651 mGpsNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002652 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002653 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002654
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002655 public void noteStopGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002656 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002657 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002658 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002659 mGpsNesting--;
2660 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002661 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002662 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
2663 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002664 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002665 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002666 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002668
Jeff Browne95c3cd2014-05-02 16:59:26 -07002669 public void noteScreenStateLocked(int state) {
2670 if (mScreenState != state) {
2671 final int oldState = mScreenState;
2672 mScreenState = state;
2673 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
2674 + ", newState=" + Display.stateToString(state));
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002675
Jeff Browne95c3cd2014-05-02 16:59:26 -07002676 if (state == Display.STATE_ON) {
2677 // Screen turning on.
2678 final long elapsedRealtime = SystemClock.elapsedRealtime();
2679 final long uptime = SystemClock.uptimeMillis();
2680 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
2681 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
2682 + Integer.toHexString(mHistoryCur.states));
2683 addHistoryRecordLocked(elapsedRealtime, uptime);
2684 mScreenOnTimer.startRunningLocked(elapsedRealtime);
2685 if (mScreenBrightnessBin >= 0) {
2686 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
2687 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002688
Jeff Browne95c3cd2014-05-02 16:59:26 -07002689 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false,
2690 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002691
Jeff Browne95c3cd2014-05-02 16:59:26 -07002692 // Fake a wake lock, so we consider the device waked as long
2693 // as the screen is on.
2694 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
2695 elapsedRealtime, uptime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002696
Jeff Browne95c3cd2014-05-02 16:59:26 -07002697 // Update discharge amounts.
2698 if (mOnBatteryInternal) {
2699 updateDischargeScreenLevelsLocked(false, true);
2700 }
2701 } else if (oldState == Display.STATE_ON) {
2702 // Screen turning off or dozing.
2703 final long elapsedRealtime = SystemClock.elapsedRealtime();
2704 final long uptime = SystemClock.uptimeMillis();
2705 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
2706 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
2707 + Integer.toHexString(mHistoryCur.states));
2708 addHistoryRecordLocked(elapsedRealtime, uptime);
2709 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
2710 if (mScreenBrightnessBin >= 0) {
2711 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
2712 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002713
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002714 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL,
Jeff Browne95c3cd2014-05-02 16:59:26 -07002715 elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002716
Jeff Browne95c3cd2014-05-02 16:59:26 -07002717 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
2718 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002719
Jeff Browne95c3cd2014-05-02 16:59:26 -07002720 // Update discharge amounts.
2721 if (mOnBatteryInternal) {
2722 updateDischargeScreenLevelsLocked(true, false);
2723 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08002724 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002725 }
2726 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002727
Dianne Hackborn617f8772009-03-31 15:04:46 -07002728 public void noteScreenBrightnessLocked(int brightness) {
2729 // Bin the brightness.
2730 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
2731 if (bin < 0) bin = 0;
2732 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
2733 if (mScreenBrightnessBin != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002734 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002735 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002736 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
2737 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002738 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
2739 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002740 addHistoryRecordLocked(elapsedRealtime, uptime);
Jeff Browne95c3cd2014-05-02 16:59:26 -07002741 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002742 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002743 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002744 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002745 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002746 }
2747 mScreenBrightnessBin = bin;
2748 }
2749 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002750
Dianne Hackborn617f8772009-03-31 15:04:46 -07002751 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002752 if (mOnBatteryInternal) {
2753 uid = mapUid(uid);
2754 getUidStatsLocked(uid).noteUserActivityLocked(event);
2755 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002757
Jeff Browne95c3cd2014-05-02 16:59:26 -07002758 public void noteInteractiveLocked(boolean interactive) {
2759 if (mInteractive != interactive) {
2760 final long elapsedRealtime = SystemClock.elapsedRealtime();
2761 mInteractive = interactive;
2762 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
2763 if (interactive) {
2764 mInteractiveTimer.startRunningLocked(elapsedRealtime);
2765 } else {
2766 mInteractiveTimer.stopRunningLocked(elapsedRealtime);
2767 }
2768 }
2769 }
2770
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07002771 public void noteMobileRadioPowerState(int powerState, long timestampNs) {
2772 final long elapsedRealtime = SystemClock.elapsedRealtime();
2773 final long uptime = SystemClock.uptimeMillis();
2774 if (mMobileRadioPowerState != powerState) {
2775 long realElapsedRealtimeMs;
2776 final boolean active =
2777 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
2778 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
2779 if (active) {
2780 realElapsedRealtimeMs = elapsedRealtime;
2781 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
2782 } else {
2783 realElapsedRealtimeMs = timestampNs / (1000*1000);
2784 long lastUpdateTimeMs = mMobileRadioActiveTimer.getLastUpdateTimeMs();
2785 if (realElapsedRealtimeMs < lastUpdateTimeMs) {
2786 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
2787 + " is before start time " + lastUpdateTimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002788 realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07002789 } else if (realElapsedRealtimeMs < elapsedRealtime) {
2790 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
2791 - realElapsedRealtimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002792 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07002793 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
2794 }
2795 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
2796 + Integer.toHexString(mHistoryCur.states));
2797 addHistoryRecordLocked(elapsedRealtime, uptime);
2798 mMobileRadioPowerState = powerState;
2799 if (active) {
2800 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
2801 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
2802 } else {
2803 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
2804 updateNetworkActivityLocked(NET_UPDATE_MOBILE, realElapsedRealtimeMs);
2805 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002806 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002807 }
2808 }
2809
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002810 public void noteLowPowerMode(boolean enabled) {
2811 if (mLowPowerModeEnabled != enabled) {
2812 final long elapsedRealtime = SystemClock.elapsedRealtime();
2813 final long uptime = SystemClock.uptimeMillis();
2814 mLowPowerModeEnabled = enabled;
2815 if (enabled) {
2816 mHistoryCur.states2 |= HistoryItem.STATE2_LOW_POWER_FLAG;
2817 if (DEBUG_HISTORY) Slog.v(TAG, "Low power mode enabled to: "
2818 + Integer.toHexString(mHistoryCur.states2));
2819 mLowPowerModeEnabledTimer.startRunningLocked(elapsedRealtime);
2820 } else {
2821 mHistoryCur.states2 &= ~HistoryItem.STATE2_LOW_POWER_FLAG;
2822 if (DEBUG_HISTORY) Slog.v(TAG, "Low power mode disabled to: "
2823 + Integer.toHexString(mHistoryCur.states2));
2824 mLowPowerModeEnabledTimer.stopRunningLocked(elapsedRealtime);
2825 }
2826 addHistoryRecordLocked(elapsedRealtime, uptime);
2827 }
2828 }
2829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002830 public void notePhoneOnLocked() {
2831 if (!mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002832 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002833 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002834 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002835 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
2836 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002837 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 mPhoneOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002839 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002840 }
2841 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 public void notePhoneOffLocked() {
2844 if (mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002845 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002846 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002847 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002848 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
2849 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002850 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 mPhoneOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002852 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 }
2854 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002855
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002856 void stopAllSignalStrengthTimersLocked(int except) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002857 final long elapsedRealtime = SystemClock.elapsedRealtime();
Wink Saville52840902011-02-18 12:40:47 -08002858 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002859 if (i == except) {
2860 continue;
2861 }
2862 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002863 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002864 }
2865 }
2866 }
2867
Dianne Hackborne4a59512010-12-07 11:08:07 -08002868 private int fixPhoneServiceState(int state, int signalBin) {
2869 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
2870 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2871 // to infer that we are scanning from other data.
2872 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08002873 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002874 state = ServiceState.STATE_IN_SERVICE;
2875 }
2876 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002877
Dianne Hackborne4a59512010-12-07 11:08:07 -08002878 return state;
2879 }
2880
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002881 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002882 boolean scanning = false;
2883 boolean newHistory = false;
2884
2885 mPhoneServiceStateRaw = state;
2886 mPhoneSimStateRaw = simState;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002887 mPhoneSignalStrengthBinRaw = strengthBin;
2888
2889 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002890 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne4a59512010-12-07 11:08:07 -08002891
2892 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
2893 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2894 // to infer that we are scanning from other data.
2895 if (state == ServiceState.STATE_OUT_OF_SERVICE
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002896 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002897 state = ServiceState.STATE_IN_SERVICE;
2898 }
2899 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002900
2901 // If the phone is powered off, stop all timers.
2902 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002903 strengthBin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002904
Dianne Hackborne4a59512010-12-07 11:08:07 -08002905 // If we are in service, make sure the correct signal string timer is running.
2906 } else if (state == ServiceState.STATE_IN_SERVICE) {
2907 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002908
2909 // If we're out of service, we are in the lowest signal strength
2910 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07002911 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002912 scanning = true;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002913 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002914 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002915 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08002916 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002917 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
2918 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002919 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
Amith Yamasanif37447b2009-10-08 18:28:01 -07002920 }
2921 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002922
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002923 if (!scanning) {
2924 // If we are no longer scanning, then stop the scanning timer.
2925 if (mPhoneSignalScanningTimer.isRunningLocked()) {
2926 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
2927 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
2928 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002929 newHistory = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002930 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002931 }
2932 }
2933
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002934 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002935 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
2936 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002937 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002938 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002939 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002940 mPhoneServiceState = state;
2941 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08002942
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002943 if (mPhoneSignalStrengthBin != strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002944 if (mPhoneSignalStrengthBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002945 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002946 elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002947 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002948 if (strengthBin >= 0) {
2949 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002950 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002951 }
2952 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002953 | (strengthBin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
2954 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
Dianne Hackborne4a59512010-12-07 11:08:07 -08002955 + Integer.toHexString(mHistoryCur.states));
2956 newHistory = true;
2957 } else {
2958 stopAllSignalStrengthTimersLocked(-1);
2959 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002960 mPhoneSignalStrengthBin = strengthBin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08002961 }
2962
2963 if (newHistory) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002964 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002965 }
2966 }
2967
2968 /**
2969 * Telephony stack updates the phone state.
2970 * @param state phone state from ServiceState.getState()
2971 */
2972 public void notePhoneStateLocked(int state, int simState) {
2973 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002974 }
2975
Wink Savillee9b06d72009-05-18 21:47:50 -07002976 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07002977 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08002978 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08002979 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002980 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002981
Dianne Hackborn627bba72009-03-24 22:32:56 -07002982 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
2983 int bin = DATA_CONNECTION_NONE;
2984 if (hasData) {
2985 switch (dataType) {
2986 case TelephonyManager.NETWORK_TYPE_EDGE:
2987 bin = DATA_CONNECTION_EDGE;
2988 break;
2989 case TelephonyManager.NETWORK_TYPE_GPRS:
2990 bin = DATA_CONNECTION_GPRS;
2991 break;
2992 case TelephonyManager.NETWORK_TYPE_UMTS:
2993 bin = DATA_CONNECTION_UMTS;
2994 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002995 case TelephonyManager.NETWORK_TYPE_CDMA:
2996 bin = DATA_CONNECTION_CDMA;
2997 break;
2998 case TelephonyManager.NETWORK_TYPE_EVDO_0:
2999 bin = DATA_CONNECTION_EVDO_0;
3000 break;
3001 case TelephonyManager.NETWORK_TYPE_EVDO_A:
3002 bin = DATA_CONNECTION_EVDO_A;
3003 break;
3004 case TelephonyManager.NETWORK_TYPE_1xRTT:
3005 bin = DATA_CONNECTION_1xRTT;
3006 break;
3007 case TelephonyManager.NETWORK_TYPE_HSDPA:
3008 bin = DATA_CONNECTION_HSDPA;
3009 break;
3010 case TelephonyManager.NETWORK_TYPE_HSUPA:
3011 bin = DATA_CONNECTION_HSUPA;
3012 break;
3013 case TelephonyManager.NETWORK_TYPE_HSPA:
3014 bin = DATA_CONNECTION_HSPA;
3015 break;
3016 case TelephonyManager.NETWORK_TYPE_IDEN:
3017 bin = DATA_CONNECTION_IDEN;
3018 break;
3019 case TelephonyManager.NETWORK_TYPE_EVDO_B:
3020 bin = DATA_CONNECTION_EVDO_B;
3021 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07003022 case TelephonyManager.NETWORK_TYPE_LTE:
3023 bin = DATA_CONNECTION_LTE;
3024 break;
3025 case TelephonyManager.NETWORK_TYPE_EHRPD:
3026 bin = DATA_CONNECTION_EHRPD;
3027 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08003028 case TelephonyManager.NETWORK_TYPE_HSPAP:
3029 bin = DATA_CONNECTION_HSPAP;
3030 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07003031 default:
3032 bin = DATA_CONNECTION_OTHER;
3033 break;
3034 }
3035 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003036 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003037 if (mPhoneDataConnectionType != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003038 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003039 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003040 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
3041 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003042 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
3043 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003044 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003045 if (mPhoneDataConnectionType >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003046 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003047 elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003048 }
3049 mPhoneDataConnectionType = bin;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003050 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003051 }
3052 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003053
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003054 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07003055 if (!mWifiOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003056 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003057 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003058 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003059 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
3060 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003061 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003062 mWifiOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003063 mWifiOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003064 }
3065 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003066
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003067 public void noteWifiOffLocked() {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003068 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003069 final long uptime = SystemClock.uptimeMillis();
The Android Open Source Project10592532009-03-18 17:39:46 -07003070 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003071 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003072 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
3073 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003074 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003075 mWifiOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003076 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003077 }
3078 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003079
3080 public void noteAudioOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003081 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003082 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003083 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003084 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003085 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003086 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
3087 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003088 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003089 mAudioOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003090 mAudioOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003091 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003092 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003093 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003094
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003095 public void noteAudioOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003096 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003097 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003098 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003099 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003100 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003101 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3102 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003103 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003104 mAudioOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003105 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003106 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003107 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003108 }
3109
3110 public void noteVideoOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003111 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003112 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003113 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003114 if (!mVideoOn) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003115 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003116 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
3117 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003118 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003119 mVideoOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003120 mVideoOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003121 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003122 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003123 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003124
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003125 public void noteVideoOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003126 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003127 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003128 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003129 if (mVideoOn) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003130 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003131 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3132 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003133 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003134 mVideoOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003135 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003136 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003137 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003138 }
3139
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003140 public void noteActivityResumedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003141 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003142 getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003143 }
3144
3145 public void noteActivityPausedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003146 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003147 getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003148 }
3149
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003150 public void noteVibratorOnLocked(int uid, long durationMillis) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003151 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003152 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
3153 }
3154
3155 public void noteVibratorOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003156 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003157 getUidStatsLocked(uid).noteVibratorOffLocked();
3158 }
3159
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003160 public void noteWifiRunningLocked(WorkSource ws) {
3161 if (!mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003162 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003163 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003164 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003165 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
3166 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003167 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003168 mGlobalWifiRunning = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003169 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003170 int N = ws.size();
3171 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003172 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003173 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003174 }
3175 } else {
3176 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003177 }
3178 }
3179
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003180 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
3181 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003182 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003183 int N = oldWs.size();
3184 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003185 int uid = mapUid(oldWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003186 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003187 }
3188 N = newWs.size();
3189 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003190 int uid = mapUid(newWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003191 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003192 }
3193 } else {
3194 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
3195 }
3196 }
3197
3198 public void noteWifiStoppedLocked(WorkSource ws) {
3199 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003200 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003201 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003202 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003203 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
3204 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003205 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003206 mGlobalWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003207 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003208 int N = ws.size();
3209 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003210 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003211 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003212 }
3213 } else {
3214 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003215 }
3216 }
3217
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003218 public void noteWifiStateLocked(int wifiState, String accessPoint) {
3219 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
3220 if (mWifiState != wifiState) {
3221 final long elapsedRealtime = SystemClock.elapsedRealtime();
3222 if (mWifiState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003223 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003224 }
3225 mWifiState = wifiState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003226 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003227 }
3228 }
3229
The Android Open Source Project10592532009-03-18 17:39:46 -07003230 public void noteBluetoothOnLocked() {
3231 if (!mBluetoothOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003232 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003233 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003234 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003235 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
3236 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003237 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003238 mBluetoothOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003239 mBluetoothOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003240 }
3241 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003242
The Android Open Source Project10592532009-03-18 17:39:46 -07003243 public void noteBluetoothOffLocked() {
3244 if (mBluetoothOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003245 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003246 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003247 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003248 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
3249 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003250 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003251 mBluetoothOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003252 mBluetoothOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003253 }
3254 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003255
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003256 public void noteBluetoothStateLocked(int bluetoothState) {
3257 if (DEBUG) Log.i(TAG, "Bluetooth state -> " + bluetoothState);
3258 if (mBluetoothState != bluetoothState) {
3259 final long elapsedRealtime = SystemClock.elapsedRealtime();
3260 if (mBluetoothState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003261 mBluetoothStateTimer[mBluetoothState].stopRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003262 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003263 mBluetoothState = bluetoothState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003264 mBluetoothStateTimer[bluetoothState].startRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003265 }
3266 }
3267
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003268 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003269
The Android Open Source Project10592532009-03-18 17:39:46 -07003270 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003271 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003272 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003273 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003274 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003275 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003276 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
3277 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003278 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003279 }
3280 mWifiFullLockNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003281 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003282 }
3283
3284 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003285 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003286 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003287 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003288 mWifiFullLockNesting--;
3289 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003290 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003291 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
3292 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003293 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003294 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003295 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003296 }
3297
Nick Pelly6ccaa542012-06-15 15:22:47 -07003298 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003299
Nick Pelly6ccaa542012-06-15 15:22:47 -07003300 public void noteWifiScanStartedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003301 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003302 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003303 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003304 if (mWifiScanNesting == 0) {
3305 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
3306 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003307 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003308 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003309 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003310 mWifiScanNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003311 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003312 }
3313
Nick Pelly6ccaa542012-06-15 15:22:47 -07003314 public void noteWifiScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003315 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003316 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003317 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003318 mWifiScanNesting--;
3319 if (mWifiScanNesting == 0) {
3320 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
3321 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003322 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003323 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003324 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003325 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003326 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003327
Robert Greenwalta029ea12013-09-25 16:38:12 -07003328 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003329 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003330 final long elapsedRealtime = SystemClock.elapsedRealtime();
3331 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003332 }
3333
3334 public void noteWifiBatchedScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003335 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003336 final long elapsedRealtime = SystemClock.elapsedRealtime();
3337 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003338 }
3339
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003340 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003341
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003342 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003343 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003344 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003345 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003346 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003347 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003348 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
3349 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003350 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003351 }
3352 mWifiMulticastNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003353 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003354 }
3355
3356 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003357 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003358 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003359 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003360 mWifiMulticastNesting--;
3361 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003362 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003363 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
3364 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003365 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003366 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003367 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003368 }
3369
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003370 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
3371 int N = ws.size();
3372 for (int i=0; i<N; i++) {
3373 noteFullWifiLockAcquiredLocked(ws.get(i));
3374 }
3375 }
3376
3377 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
3378 int N = ws.size();
3379 for (int i=0; i<N; i++) {
3380 noteFullWifiLockReleasedLocked(ws.get(i));
3381 }
3382 }
3383
Nick Pelly6ccaa542012-06-15 15:22:47 -07003384 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003385 int N = ws.size();
3386 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003387 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003388 }
3389 }
3390
Nick Pelly6ccaa542012-06-15 15:22:47 -07003391 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003392 int N = ws.size();
3393 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003394 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003395 }
3396 }
3397
Robert Greenwalta029ea12013-09-25 16:38:12 -07003398 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
3399 int N = ws.size();
3400 for (int i=0; i<N; i++) {
3401 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
3402 }
3403 }
3404
3405 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
3406 int N = ws.size();
3407 for (int i=0; i<N; i++) {
3408 noteWifiBatchedScanStoppedLocked(ws.get(i));
3409 }
3410 }
3411
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003412 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
3413 int N = ws.size();
3414 for (int i=0; i<N; i++) {
3415 noteWifiMulticastEnabledLocked(ws.get(i));
3416 }
3417 }
3418
3419 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
3420 int N = ws.size();
3421 for (int i=0; i<N; i++) {
3422 noteWifiMulticastDisabledLocked(ws.get(i));
3423 }
3424 }
3425
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003426 private static String[] includeInStringArray(String[] array, String str) {
3427 if (ArrayUtils.indexOf(array, str) >= 0) {
3428 return array;
3429 }
3430 String[] newArray = new String[array.length+1];
3431 System.arraycopy(array, 0, newArray, 0, array.length);
3432 newArray[array.length] = str;
3433 return newArray;
3434 }
3435
3436 private static String[] excludeFromStringArray(String[] array, String str) {
3437 int index = ArrayUtils.indexOf(array, str);
3438 if (index >= 0) {
3439 String[] newArray = new String[array.length-1];
3440 if (index > 0) {
3441 System.arraycopy(array, 0, newArray, 0, index);
3442 }
3443 if (index < array.length-1) {
3444 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
3445 }
3446 return newArray;
3447 }
3448 return array;
3449 }
3450
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003451 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
3452 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003453 mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
3454 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003455 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003456 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
3457 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003458 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003459 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003460 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
3461 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003462 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003463 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
3464 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003465 }
3466 }
3467
3468 public void noteNetworkStatsEnabledLocked() {
3469 // During device boot, qtaguid isn't enabled until after the inital
3470 // loading of battery stats. Now that they're enabled, take our initial
3471 // snapshot for future delta calculation.
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003472 updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003473 }
3474
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003475 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
3476 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003477 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003478
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003479 @Override public int getScreenOnCount(int which) {
3480 return mScreenOnTimer.getCountLocked(which);
3481 }
3482
Dianne Hackborn617f8772009-03-31 15:04:46 -07003483 @Override public long getScreenBrightnessTime(int brightnessBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003484 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003485 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003486 elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003487 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003488
Jeff Browne95c3cd2014-05-02 16:59:26 -07003489 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
3490 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003491 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003492
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003493 @Override public long getLowPowerModeEnabledTime(long elapsedRealtimeUs, int which) {
3494 return mLowPowerModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
3495 }
3496
3497 @Override public int getLowPowerModeEnabledCount(int which) {
3498 return mLowPowerModeEnabledTimer.getCountLocked(which);
3499 }
3500
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003501 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
3502 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003503 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003504
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003505 @Override public int getPhoneOnCount(int which) {
3506 return mPhoneOnTimer.getCountLocked(which);
3507 }
3508
Dianne Hackborn627bba72009-03-24 22:32:56 -07003509 @Override public long getPhoneSignalStrengthTime(int strengthBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003510 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003511 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003512 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003513 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003514
3515 @Override public long getPhoneSignalScanningTime(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003516 long elapsedRealtimeUs, int which) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07003517 return mPhoneSignalScanningTimer.getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003518 elapsedRealtimeUs, which);
Amith Yamasanif37447b2009-10-08 18:28:01 -07003519 }
3520
Catherine Liufb900812012-07-17 14:12:56 -05003521 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
3522 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003523 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003524
Dianne Hackborn627bba72009-03-24 22:32:56 -07003525 @Override public long getPhoneDataConnectionTime(int dataType,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003526 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003527 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003528 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003529 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003530
Dianne Hackborn617f8772009-03-31 15:04:46 -07003531 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003532 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003533 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003534
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003535 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
3536 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003537 }
3538
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003539 @Override public int getMobileRadioActiveCount(int which) {
3540 return mMobileRadioActiveTimer.getCountLocked(which);
3541 }
3542
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003543 @Override public long getMobileRadioActiveAdjustedTime(int which) {
3544 return mMobileRadioActiveAdjustedTime.getCountLocked(which);
3545 }
3546
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003547 @Override public long getMobileRadioActiveUnknownTime(int which) {
3548 return mMobileRadioActiveUnknownTime.getCountLocked(which);
3549 }
3550
3551 @Override public int getMobileRadioActiveUnknownCount(int which) {
3552 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
3553 }
3554
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003555 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
3556 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003557 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003558
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003559 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
3560 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003561 }
3562
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003563 @Override public long getWifiStateTime(int wifiState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003564 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003565 return mWifiStateTimer[wifiState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003566 elapsedRealtimeUs, which);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003567 }
3568
3569 @Override public int getWifiStateCount(int wifiState, int which) {
3570 return mWifiStateTimer[wifiState].getCountLocked(which);
3571 }
3572
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003573 @Override public long getBluetoothOnTime(long elapsedRealtimeUs, int which) {
3574 return mBluetoothOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003575 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003576
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003577 @Override public long getBluetoothStateTime(int bluetoothState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003578 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003579 return mBluetoothStateTimer[bluetoothState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003580 elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003581 }
3582
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003583 @Override public int getBluetoothStateCount(int bluetoothState, int which) {
3584 return mBluetoothStateTimer[bluetoothState].getCountLocked(which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003585 }
3586
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003587 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003588 public long getNetworkActivityBytes(int type, int which) {
3589 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
3590 return mNetworkByteActivityCounters[type].getCountLocked(which);
3591 } else {
3592 return 0;
3593 }
3594 }
3595
3596 @Override
3597 public long getNetworkActivityPackets(int type, int which) {
3598 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
3599 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003600 } else {
3601 return 0;
3602 }
3603 }
3604
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08003605 @Override public long getStartClockTime() {
3606 return mStartClockTime;
3607 }
3608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003609 @Override public boolean getIsOnBattery() {
3610 return mOnBattery;
3611 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003613 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
3614 return mUidStats;
3615 }
3616
3617 /**
3618 * The statistics associated with a particular uid.
3619 */
3620 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003623
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003624 boolean mWifiRunning;
3625 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003626
The Android Open Source Project10592532009-03-18 17:39:46 -07003627 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07003628 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003629
Nick Pelly6ccaa542012-06-15 15:22:47 -07003630 boolean mWifiScanStarted;
3631 StopwatchTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003632
Robert Greenwalta029ea12013-09-25 16:38:12 -07003633 private static final int NO_BATCHED_SCAN_STARTED = -1;
3634 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
3635 StopwatchTimer[] mWifiBatchedScanTimer;
3636
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003637 boolean mWifiMulticastEnabled;
3638 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003639
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003640 boolean mAudioTurnedOn;
3641 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003642
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003643 boolean mVideoTurnedOn;
3644 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003645
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003646 StopwatchTimer mForegroundActivityTimer;
3647
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003648 BatchTimer mVibratorOnTimer;
3649
Dianne Hackborn617f8772009-03-31 15:04:46 -07003650 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003651
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003652 LongSamplingCounter[] mNetworkByteActivityCounters;
3653 LongSamplingCounter[] mNetworkPacketActivityCounters;
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003654 LongSamplingCounter mMobileRadioActiveTime;
3655 LongSamplingCounter mMobileRadioActiveCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 /**
3658 * The statistics we have collected for this uid's wake locks.
3659 */
3660 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
3661
3662 /**
3663 * The statistics we have collected for this uid's sensor activations.
3664 */
3665 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
3666
3667 /**
3668 * The statistics we have collected for this uid's processes.
3669 */
3670 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
3671
3672 /**
3673 * The statistics we have collected for this uid's processes.
3674 */
3675 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003676
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003677 /**
3678 * The transient wake stats we have collected for this uid's pids.
3679 */
3680 final SparseArray<Pid> mPids = new SparseArray<Pid>();
3681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003682 public Uid(int uid) {
3683 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003684 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003685 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003686 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003687 mFullWifiLockTimers, mOnBatteryTimeBase);
Nick Pelly6ccaa542012-06-15 15:22:47 -07003688 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003689 mWifiScanTimers, mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003690 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003691 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003692 mWifiMulticastTimers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003693 }
3694
3695 @Override
3696 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
3697 return mWakelockStats;
3698 }
3699
3700 @Override
3701 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
3702 return mSensorStats;
3703 }
3704
3705 @Override
3706 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
3707 return mProcessStats;
3708 }
3709
3710 @Override
3711 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
3712 return mPackageStats;
3713 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003714
3715 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003716 public int getUid() {
3717 return mUid;
3718 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003719
3720 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003721 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003722 if (!mWifiRunning) {
3723 mWifiRunning = true;
3724 if (mWifiRunningTimer == null) {
3725 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003726 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003727 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003728 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003729 }
3730 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003731
Dianne Hackborn617f8772009-03-31 15:04:46 -07003732 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003733 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003734 if (mWifiRunning) {
3735 mWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003736 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003737 }
3738 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003739
Dianne Hackborn617f8772009-03-31 15:04:46 -07003740 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003741 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003742 if (!mFullWifiLockOut) {
3743 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003744 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003745 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003746 mFullWifiLockTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003747 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003748 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003749 }
3750 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003751
The Android Open Source Project10592532009-03-18 17:39:46 -07003752 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003753 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003754 if (mFullWifiLockOut) {
3755 mFullWifiLockOut = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003756 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003757 }
3758 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003759
The Android Open Source Project10592532009-03-18 17:39:46 -07003760 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003761 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003762 if (!mWifiScanStarted) {
3763 mWifiScanStarted = true;
3764 if (mWifiScanTimer == null) {
3765 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003766 mWifiScanTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003767 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003768 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003769 }
3770 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003771
The Android Open Source Project10592532009-03-18 17:39:46 -07003772 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003773 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003774 if (mWifiScanStarted) {
3775 mWifiScanStarted = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003776 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003777 }
3778 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003779
3780 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003781 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07003782 int bin = 0;
3783 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
3784 csph = csph >> 3;
3785 bin++;
3786 }
3787
3788 if (mWifiBatchedScanBinStarted == bin) return;
3789
3790 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
3791 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003792 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003793 }
3794 mWifiBatchedScanBinStarted = bin;
3795 if (mWifiBatchedScanTimer[bin] == null) {
3796 makeWifiBatchedScanBin(bin, null);
3797 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003798 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003799 }
3800
3801 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003802 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07003803 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
3804 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003805 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003806 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
3807 }
3808 }
3809
3810 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003811 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003812 if (!mWifiMulticastEnabled) {
3813 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003814 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003815 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003816 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003817 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003818 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003819 }
3820 }
3821
3822 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003823 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003824 if (mWifiMulticastEnabled) {
3825 mWifiMulticastEnabled = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003826 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003827 }
3828 }
3829
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003830 public StopwatchTimer createAudioTurnedOnTimerLocked() {
3831 if (mAudioTurnedOnTimer == null) {
3832 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003833 null, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003834 }
3835 return mAudioTurnedOnTimer;
3836 }
3837
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003838 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003839 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003840 if (!mAudioTurnedOn) {
3841 mAudioTurnedOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003842 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003843 }
3844 }
3845
3846 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003847 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003848 if (mAudioTurnedOn) {
3849 mAudioTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003850 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003851 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003852 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003853 }
3854 }
3855
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003856 public StopwatchTimer createVideoTurnedOnTimerLocked() {
3857 if (mVideoTurnedOnTimer == null) {
3858 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003859 null, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003860 }
3861 return mVideoTurnedOnTimer;
3862 }
3863
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003864 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003865 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003866 if (!mVideoTurnedOn) {
3867 mVideoTurnedOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003868 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003869 }
3870 }
3871
3872 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003873 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003874 if (mVideoTurnedOn) {
3875 mVideoTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003876 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003877 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003878 }
3879 }
3880 }
3881
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003882 public StopwatchTimer createForegroundActivityTimerLocked() {
3883 if (mForegroundActivityTimer == null) {
3884 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003885 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003886 }
3887 return mForegroundActivityTimer;
3888 }
3889
3890 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003891 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003892 // We always start, since we want multiple foreground PIDs to nest
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003893 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003894 }
3895
3896 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003897 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003898 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003899 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003900 }
3901 }
3902
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003903 public BatchTimer createVibratorOnTimerLocked() {
3904 if (mVibratorOnTimer == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003905 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003906 }
3907 return mVibratorOnTimer;
3908 }
3909
3910 public void noteVibratorOnLocked(long durationMillis) {
3911 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
3912 }
3913
3914 public void noteVibratorOffLocked() {
3915 if (mVibratorOnTimer != null) {
3916 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003917 }
3918 }
3919
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003920 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003921 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003922 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003923 return 0;
3924 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003925 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003926 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003927
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003928 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003929 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003930 if (mFullWifiLockTimer == null) {
3931 return 0;
3932 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003933 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003934 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003935
3936 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003937 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003938 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003939 return 0;
3940 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003941 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003942 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003943
3944 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003945 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07003946 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
3947 if (mWifiBatchedScanTimer[csphBin] == null) {
3948 return 0;
3949 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003950 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003951 }
3952
3953 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003954 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003955 if (mWifiMulticastTimer == null) {
3956 return 0;
3957 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003958 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003959 }
3960
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003961 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003962 public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003963 if (mAudioTurnedOnTimer == null) {
3964 return 0;
3965 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003966 return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003967 }
3968
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003969 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003970 public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003971 if (mVideoTurnedOnTimer == null) {
3972 return 0;
3973 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003974 return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003975 }
3976
Dianne Hackborn617f8772009-03-31 15:04:46 -07003977 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003978 public Timer getForegroundActivityTimer() {
3979 return mForegroundActivityTimer;
3980 }
3981
3982 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003983 public Timer getVibratorOnTimer() {
3984 return mVibratorOnTimer;
3985 }
3986
3987 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07003988 public void noteUserActivityLocked(int type) {
3989 if (mUserActivityCounters == null) {
3990 initUserActivityLocked();
3991 }
Jeff Browndf693de2012-07-27 12:03:38 -07003992 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
3993 mUserActivityCounters[type].stepAtomic();
3994 } else {
3995 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
3996 new Throwable());
3997 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07003998 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003999
Dianne Hackborn617f8772009-03-31 15:04:46 -07004000 @Override
4001 public boolean hasUserActivity() {
4002 return mUserActivityCounters != null;
4003 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004004
Dianne Hackborn617f8772009-03-31 15:04:46 -07004005 @Override
4006 public int getUserActivityCount(int type, int which) {
4007 if (mUserActivityCounters == null) {
4008 return 0;
4009 }
Evan Millarc64edde2009-04-18 12:26:32 -07004010 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004011 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004012
Robert Greenwalta029ea12013-09-25 16:38:12 -07004013 void makeWifiBatchedScanBin(int i, Parcel in) {
4014 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
4015
4016 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i);
4017 if (collected == null) {
4018 collected = new ArrayList<StopwatchTimer>();
4019 mWifiBatchedScanTimers.put(i, collected);
4020 }
4021 if (in == null) {
4022 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004023 mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004024 } else {
4025 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004026 mOnBatteryTimeBase, in);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004027 }
4028 }
4029
4030
Dianne Hackborn617f8772009-03-31 15:04:46 -07004031 void initUserActivityLocked() {
4032 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
4033 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004034 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004035 }
4036 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004037
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004038 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
4039 if (mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004040 initNetworkActivityLocked();
4041 }
4042 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004043 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
4044 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004045 } else {
4046 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
4047 new Throwable());
4048 }
4049 }
4050
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004051 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
4052 if (mNetworkByteActivityCounters == null) {
4053 initNetworkActivityLocked();
4054 }
4055 mMobileRadioActiveTime.addCountLocked(batteryUptime);
4056 mMobileRadioActiveCount.addCountLocked(1);
4057 }
4058
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004059 @Override
4060 public boolean hasNetworkActivity() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004061 return mNetworkByteActivityCounters != null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004062 }
4063
4064 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004065 public long getNetworkActivityBytes(int type, int which) {
4066 if (mNetworkByteActivityCounters != null && type >= 0
4067 && type < mNetworkByteActivityCounters.length) {
4068 return mNetworkByteActivityCounters[type].getCountLocked(which);
4069 } else {
4070 return 0;
4071 }
4072 }
4073
4074 @Override
4075 public long getNetworkActivityPackets(int type, int which) {
4076 if (mNetworkPacketActivityCounters != null && type >= 0
4077 && type < mNetworkPacketActivityCounters.length) {
4078 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004079 } else {
4080 return 0;
4081 }
4082 }
4083
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004084 @Override
4085 public long getMobileRadioActiveTime(int which) {
4086 return mMobileRadioActiveTime != null
4087 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
4088 }
4089
4090 @Override
4091 public int getMobileRadioActiveCount(int which) {
4092 return mMobileRadioActiveCount != null
4093 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
4094 }
4095
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004096 void initNetworkActivityLocked() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004097 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
4098 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004099 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004100 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
4101 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004102 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004103 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase);
4104 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004105 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004106
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004107 /**
4108 * Clear all stats for this uid. Returns true if the uid is completely
4109 * inactive so can be dropped.
4110 */
4111 boolean reset() {
4112 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004113
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004114 if (mWifiRunningTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004115 active |= !mWifiRunningTimer.reset(false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004116 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004117 }
4118 if (mFullWifiLockTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004119 active |= !mFullWifiLockTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004120 active |= mFullWifiLockOut;
4121 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004122 if (mWifiScanTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004123 active |= !mWifiScanTimer.reset(false);
Nick Pelly6ccaa542012-06-15 15:22:47 -07004124 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004125 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004126 if (mWifiBatchedScanTimer != null) {
4127 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4128 if (mWifiBatchedScanTimer[i] != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004129 active |= !mWifiBatchedScanTimer[i].reset(false);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004130 }
4131 }
4132 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
4133 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004134 if (mWifiMulticastTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004135 active |= !mWifiMulticastTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004136 active |= mWifiMulticastEnabled;
4137 }
4138 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004139 active |= !mAudioTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004140 active |= mAudioTurnedOn;
4141 }
4142 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004143 active |= !mVideoTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004144 active |= mVideoTurnedOn;
4145 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004146 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004147 active |= !mForegroundActivityTimer.reset(false);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004148 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004149 if (mVibratorOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004150 if (mVibratorOnTimer.reset(false)) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004151 mVibratorOnTimer.detach();
4152 mVibratorOnTimer = null;
4153 } else {
4154 active = true;
4155 }
4156 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004157
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004158 if (mUserActivityCounters != null) {
4159 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
4160 mUserActivityCounters[i].reset(false);
4161 }
4162 }
4163
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004164 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004165 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004166 mNetworkByteActivityCounters[i].reset(false);
4167 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004168 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004169 mMobileRadioActiveTime.reset(false);
4170 mMobileRadioActiveCount.reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004171 }
4172
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004173 if (mWakelockStats.size() > 0) {
4174 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
4175 while (it.hasNext()) {
4176 Map.Entry<String, Wakelock> wakelockEntry = it.next();
4177 Wakelock wl = wakelockEntry.getValue();
4178 if (wl.reset()) {
4179 it.remove();
4180 } else {
4181 active = true;
4182 }
4183 }
4184 }
4185 if (mSensorStats.size() > 0) {
4186 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
4187 while (it.hasNext()) {
4188 Map.Entry<Integer, Sensor> sensorEntry = it.next();
4189 Sensor s = sensorEntry.getValue();
4190 if (s.reset()) {
4191 it.remove();
4192 } else {
4193 active = true;
4194 }
4195 }
4196 }
4197 if (mProcessStats.size() > 0) {
4198 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
4199 while (it.hasNext()) {
4200 Map.Entry<String, Proc> procEntry = it.next();
4201 procEntry.getValue().detach();
4202 }
4203 mProcessStats.clear();
4204 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004205 if (mPids.size() > 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004206 for (int i=mPids.size()-1; i>=0; i--) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004207 Pid pid = mPids.valueAt(i);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004208 if (pid.mWakeNesting > 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004209 active = true;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004210 } else {
4211 mPids.removeAt(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004212 }
4213 }
4214 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004215 if (mPackageStats.size() > 0) {
4216 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
4217 while (it.hasNext()) {
4218 Map.Entry<String, Pkg> pkgEntry = it.next();
4219 Pkg p = pkgEntry.getValue();
4220 p.detach();
4221 if (p.mServiceStats.size() > 0) {
4222 Iterator<Map.Entry<String, Pkg.Serv>> it2
4223 = p.mServiceStats.entrySet().iterator();
4224 while (it2.hasNext()) {
4225 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
4226 servEntry.getValue().detach();
4227 }
4228 }
4229 }
4230 mPackageStats.clear();
4231 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004232
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004233 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004234 if (mWifiRunningTimer != null) {
4235 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004236 }
4237 if (mFullWifiLockTimer != null) {
4238 mFullWifiLockTimer.detach();
4239 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004240 if (mWifiScanTimer != null) {
4241 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004242 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004243 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4244 if (mWifiBatchedScanTimer[i] != null) {
4245 mWifiBatchedScanTimer[i].detach();
4246 }
4247 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004248 if (mWifiMulticastTimer != null) {
4249 mWifiMulticastTimer.detach();
4250 }
4251 if (mAudioTurnedOnTimer != null) {
4252 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004253 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004254 }
4255 if (mVideoTurnedOnTimer != null) {
4256 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004257 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004258 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004259 if (mForegroundActivityTimer != null) {
4260 mForegroundActivityTimer.detach();
4261 mForegroundActivityTimer = null;
4262 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004263 if (mUserActivityCounters != null) {
4264 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
4265 mUserActivityCounters[i].detach();
4266 }
4267 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004268 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004269 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004270 mNetworkByteActivityCounters[i].detach();
4271 mNetworkPacketActivityCounters[i].detach();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004272 }
4273 }
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004274 mPids.clear();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004275 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004276
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004277 return !active;
4278 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004279
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004280 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004281 out.writeInt(mWakelockStats.size());
4282 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
4283 out.writeString(wakelockEntry.getKey());
4284 Uid.Wakelock wakelock = wakelockEntry.getValue();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004285 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004286 }
4287
4288 out.writeInt(mSensorStats.size());
4289 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
4290 out.writeInt(sensorEntry.getKey());
4291 Uid.Sensor sensor = sensorEntry.getValue();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004292 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 }
4294
4295 out.writeInt(mProcessStats.size());
4296 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
4297 out.writeString(procEntry.getKey());
4298 Uid.Proc proc = procEntry.getValue();
4299 proc.writeToParcelLocked(out);
4300 }
4301
4302 out.writeInt(mPackageStats.size());
4303 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
4304 out.writeString(pkgEntry.getKey());
4305 Uid.Pkg pkg = pkgEntry.getValue();
4306 pkg.writeToParcelLocked(out);
4307 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004308
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004309 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004310 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004311 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004312 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004313 out.writeInt(0);
4314 }
4315 if (mFullWifiLockTimer != null) {
4316 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004317 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004318 } else {
4319 out.writeInt(0);
4320 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004321 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004322 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004323 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004324 } else {
4325 out.writeInt(0);
4326 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004327 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4328 if (mWifiBatchedScanTimer[i] != null) {
4329 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004330 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004331 } else {
4332 out.writeInt(0);
4333 }
4334 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004335 if (mWifiMulticastTimer != null) {
4336 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004337 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004338 } else {
4339 out.writeInt(0);
4340 }
4341 if (mAudioTurnedOnTimer != null) {
4342 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004343 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004344 } else {
4345 out.writeInt(0);
4346 }
4347 if (mVideoTurnedOnTimer != null) {
4348 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004349 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004350 } else {
4351 out.writeInt(0);
4352 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004353 if (mForegroundActivityTimer != null) {
4354 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004355 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004356 } else {
4357 out.writeInt(0);
4358 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004359 if (mVibratorOnTimer != null) {
4360 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004361 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004362 } else {
4363 out.writeInt(0);
4364 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004365 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07004366 out.writeInt(1);
4367 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
4368 mUserActivityCounters[i].writeToParcel(out);
4369 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004370 } else {
4371 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004372 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004373 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004374 out.writeInt(1);
4375 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004376 mNetworkByteActivityCounters[i].writeToParcel(out);
4377 mNetworkPacketActivityCounters[i].writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004378 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004379 mMobileRadioActiveTime.writeToParcel(out);
4380 mMobileRadioActiveCount.writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004381 } else {
4382 out.writeInt(0);
4383 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004384 }
4385
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004386 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004387 int numWakelocks = in.readInt();
4388 mWakelockStats.clear();
4389 for (int j = 0; j < numWakelocks; j++) {
4390 String wakelockName = in.readString();
4391 Uid.Wakelock wakelock = new Wakelock();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004392 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
Dianne Hackbornc24ab862011-10-18 15:55:03 -07004393 // We will just drop some random set of wakelocks if
4394 // the previous run of the system was an older version
4395 // that didn't impose a limit.
4396 mWakelockStats.put(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 }
4398
4399 int numSensors = in.readInt();
4400 mSensorStats.clear();
4401 for (int k = 0; k < numSensors; k++) {
4402 int sensorNumber = in.readInt();
4403 Uid.Sensor sensor = new Sensor(sensorNumber);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004404 sensor.readFromParcelLocked(mOnBatteryTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004405 mSensorStats.put(sensorNumber, sensor);
4406 }
4407
4408 int numProcs = in.readInt();
4409 mProcessStats.clear();
4410 for (int k = 0; k < numProcs; k++) {
4411 String processName = in.readString();
4412 Uid.Proc proc = new Proc();
4413 proc.readFromParcelLocked(in);
4414 mProcessStats.put(processName, proc);
4415 }
4416
4417 int numPkgs = in.readInt();
4418 mPackageStats.clear();
4419 for (int l = 0; l < numPkgs; l++) {
4420 String packageName = in.readString();
4421 Uid.Pkg pkg = new Pkg();
4422 pkg.readFromParcelLocked(in);
4423 mPackageStats.put(packageName, pkg);
4424 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004425
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004426 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004427 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004428 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004429 mWifiRunningTimers, mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004430 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004431 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004432 }
4433 mFullWifiLockOut = false;
4434 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004435 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004436 mFullWifiLockTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004437 } else {
4438 mFullWifiLockTimer = null;
4439 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004440 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004441 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004442 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004443 mWifiScanTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004444 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004445 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004446 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004447 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4448 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4449 if (in.readInt() != 0) {
4450 makeWifiBatchedScanBin(i, in);
4451 } else {
4452 mWifiBatchedScanTimer[i] = null;
4453 }
4454 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004455 mWifiMulticastEnabled = false;
4456 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004457 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004458 mWifiMulticastTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004459 } else {
4460 mWifiMulticastTimer = null;
4461 }
4462 mAudioTurnedOn = false;
4463 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004464 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004465 null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004466 } else {
4467 mAudioTurnedOnTimer = null;
4468 }
4469 mVideoTurnedOn = false;
4470 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004471 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004472 null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004473 } else {
4474 mVideoTurnedOnTimer = null;
4475 }
4476 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004477 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004478 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004479 } else {
4480 mForegroundActivityTimer = null;
4481 }
4482 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004483 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004484 } else {
4485 mVibratorOnTimer = null;
4486 }
4487 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07004488 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
4489 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004490 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004491 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004492 } else {
4493 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07004494 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004495 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004496 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
4497 mNetworkPacketActivityCounters
4498 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004499 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004500 mNetworkByteActivityCounters[i]
4501 = new LongSamplingCounter(mOnBatteryTimeBase, in);
4502 mNetworkPacketActivityCounters[i]
4503 = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004504 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004505 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
4506 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004507 } else {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004508 mNetworkByteActivityCounters = null;
4509 mNetworkPacketActivityCounters = null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004511 }
4512
4513 /**
4514 * The statistics associated with a particular wake lock.
4515 */
4516 public final class Wakelock extends BatteryStats.Uid.Wakelock {
4517 /**
4518 * How long (in ms) this uid has been keeping the device partially awake.
4519 */
Evan Millarc64edde2009-04-18 12:26:32 -07004520 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521
4522 /**
4523 * How long (in ms) this uid has been keeping the device fully awake.
4524 */
Evan Millarc64edde2009-04-18 12:26:32 -07004525 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526
4527 /**
4528 * How long (in ms) this uid has had a window keeping the device awake.
4529 */
Evan Millarc64edde2009-04-18 12:26:32 -07004530 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004531
4532 /**
4533 * Reads a possibly null Timer from a Parcel. The timer is associated with the
4534 * proper timer pool from the given BatteryStatsImpl object.
4535 *
4536 * @param in the Parcel to be read from.
4537 * return a new Timer, or null.
4538 */
Evan Millarc64edde2009-04-18 12:26:32 -07004539 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004540 TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004541 if (in.readInt() == 0) {
4542 return null;
4543 }
4544
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004545 return new StopwatchTimer(Uid.this, type, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004546 }
4547
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004548 boolean reset() {
4549 boolean wlactive = false;
4550 if (mTimerFull != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004551 wlactive |= !mTimerFull.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004552 }
4553 if (mTimerPartial != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004554 wlactive |= !mTimerPartial.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004555 }
4556 if (mTimerWindow != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004557 wlactive |= !mTimerWindow.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004558 }
4559 if (!wlactive) {
4560 if (mTimerFull != null) {
4561 mTimerFull.detach();
4562 mTimerFull = null;
4563 }
4564 if (mTimerPartial != null) {
4565 mTimerPartial.detach();
4566 mTimerPartial = null;
4567 }
4568 if (mTimerWindow != null) {
4569 mTimerWindow.detach();
4570 mTimerWindow = null;
4571 }
4572 }
4573 return !wlactive;
4574 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004575
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004576 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004577 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004578 mPartialTimers, screenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004579 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004580 mFullTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004582 mWindowTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004583 }
4584
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004585 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
4586 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
4587 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
4588 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004589 }
4590
4591 @Override
4592 public Timer getWakeTime(int type) {
4593 switch (type) {
4594 case WAKE_TYPE_FULL: return mTimerFull;
4595 case WAKE_TYPE_PARTIAL: return mTimerPartial;
4596 case WAKE_TYPE_WINDOW: return mTimerWindow;
4597 default: throw new IllegalArgumentException("type = " + type);
4598 }
4599 }
4600 }
4601
4602 public final class Sensor extends BatteryStats.Uid.Sensor {
4603 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07004604 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004606 public Sensor(int handle) {
4607 mHandle = handle;
4608 }
4609
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004610 private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 if (in.readInt() == 0) {
4612 return null;
4613 }
4614
Evan Millarc64edde2009-04-18 12:26:32 -07004615 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004616 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07004617 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618 mSensorTimers.put(mHandle, pool);
4619 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004620 return new StopwatchTimer(Uid.this, 0, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004621 }
4622
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004623 boolean reset() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004624 if (mTimer.reset(true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004625 mTimer = null;
4626 return true;
4627 }
4628 return false;
4629 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004630
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004631 void readFromParcelLocked(TimeBase timeBase, Parcel in) {
4632 mTimer = readTimerFromParcel(timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004633 }
4634
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004635 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
4636 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004637 }
4638
4639 @Override
4640 public Timer getSensorTime() {
4641 return mTimer;
4642 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004643
4644 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004645 public int getHandle() {
4646 return mHandle;
4647 }
4648 }
4649
4650 /**
4651 * The statistics associated with a particular process.
4652 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004653 public final class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -08004655 * Remains true until removed from the stats.
4656 */
4657 boolean mActive = true;
4658
4659 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 * Total time (in 1/100 sec) spent executing in user code.
4661 */
4662 long mUserTime;
4663
4664 /**
4665 * Total time (in 1/100 sec) spent executing in kernel code.
4666 */
4667 long mSystemTime;
4668
4669 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004670 * Amount of time the process was running in the foreground.
4671 */
4672 long mForegroundTime;
4673
4674 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004675 * Number of times the process has been started.
4676 */
4677 int mStarts;
4678
4679 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004680 * The amount of user time loaded from a previous save.
4681 */
4682 long mLoadedUserTime;
4683
4684 /**
4685 * The amount of system time loaded from a previous save.
4686 */
4687 long mLoadedSystemTime;
4688
4689 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004690 * The amount of foreground time loaded from a previous save.
4691 */
4692 long mLoadedForegroundTime;
4693
4694 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004695 * The number of times the process has started from a previous save.
4696 */
4697 int mLoadedStarts;
4698
4699 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004700 * The amount of user time loaded from the previous run.
4701 */
4702 long mLastUserTime;
4703
4704 /**
4705 * The amount of system time loaded from the previous run.
4706 */
4707 long mLastSystemTime;
4708
4709 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004710 * The amount of foreground time loaded from the previous run
4711 */
4712 long mLastForegroundTime;
4713
4714 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004715 * The number of times the process has started from the previous run.
4716 */
4717 int mLastStarts;
4718
4719 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004720 * The amount of user time when last unplugged.
4721 */
4722 long mUnpluggedUserTime;
4723
4724 /**
4725 * The amount of system time when last unplugged.
4726 */
4727 long mUnpluggedSystemTime;
4728
4729 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004730 * The amount of foreground time since unplugged.
4731 */
4732 long mUnpluggedForegroundTime;
4733
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004734 /**
4735 * The number of times the process has started before unplugged.
4736 */
4737 int mUnpluggedStarts;
4738
Amith Yamasanie43530a2009-08-21 13:11:37 -07004739 SamplingCounter[] mSpeedBins;
4740
Dianne Hackborn287952c2010-09-22 22:34:31 -07004741 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004743 Proc() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004744 mOnBatteryTimeBase.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07004745 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004746 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004747
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004748 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004749 mUnpluggedUserTime = mUserTime;
4750 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004751 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004752 mUnpluggedStarts = mStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004753 }
4754
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004755 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004756 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004757
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004758 void detach() {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004759 mActive = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004760 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004761 for (int i = 0; i < mSpeedBins.length; i++) {
4762 SamplingCounter c = mSpeedBins[i];
4763 if (c != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004764 mOnBatteryTimeBase.remove(c);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004765 mSpeedBins[i] = null;
4766 }
4767 }
4768 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004769
Dianne Hackborn287952c2010-09-22 22:34:31 -07004770 public int countExcessivePowers() {
4771 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004772 }
4773
Dianne Hackborn287952c2010-09-22 22:34:31 -07004774 public ExcessivePower getExcessivePower(int i) {
4775 if (mExcessivePower != null) {
4776 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004777 }
4778 return null;
4779 }
4780
4781 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004782 if (mExcessivePower == null) {
4783 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004784 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07004785 ExcessivePower ew = new ExcessivePower();
4786 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004787 ew.overTime = overTime;
4788 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07004789 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004790 }
4791
Dianne Hackborn287952c2010-09-22 22:34:31 -07004792 public void addExcessiveCpu(long overTime, long usedTime) {
4793 if (mExcessivePower == null) {
4794 mExcessivePower = new ArrayList<ExcessivePower>();
4795 }
4796 ExcessivePower ew = new ExcessivePower();
4797 ew.type = ExcessivePower.TYPE_CPU;
4798 ew.overTime = overTime;
4799 ew.usedTime = usedTime;
4800 mExcessivePower.add(ew);
4801 }
4802
4803 void writeExcessivePowerToParcelLocked(Parcel out) {
4804 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004805 out.writeInt(0);
4806 return;
4807 }
4808
Dianne Hackborn287952c2010-09-22 22:34:31 -07004809 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004810 out.writeInt(N);
4811 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004812 ExcessivePower ew = mExcessivePower.get(i);
4813 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004814 out.writeLong(ew.overTime);
4815 out.writeLong(ew.usedTime);
4816 }
4817 }
4818
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004819 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004820 final int N = in.readInt();
4821 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004822 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004823 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004824 }
4825
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004826 if (N > 10000) {
4827 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
4828 return false;
4829 }
4830
Dianne Hackborn287952c2010-09-22 22:34:31 -07004831 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004832 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004833 ExcessivePower ew = new ExcessivePower();
4834 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004835 ew.overTime = in.readLong();
4836 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07004837 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004838 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004839 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004840 }
4841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004842 void writeToParcelLocked(Parcel out) {
4843 out.writeLong(mUserTime);
4844 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004845 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004846 out.writeInt(mStarts);
4847 out.writeLong(mLoadedUserTime);
4848 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004849 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004850 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 out.writeLong(mUnpluggedUserTime);
4852 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004853 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004854 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07004855
4856 out.writeInt(mSpeedBins.length);
4857 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004858 SamplingCounter c = mSpeedBins[i];
4859 if (c != null) {
4860 out.writeInt(1);
4861 c.writeToParcel(out);
4862 } else {
4863 out.writeInt(0);
4864 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004865 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004866
Dianne Hackborn287952c2010-09-22 22:34:31 -07004867 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004868 }
4869
4870 void readFromParcelLocked(Parcel in) {
4871 mUserTime = in.readLong();
4872 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004873 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874 mStarts = in.readInt();
4875 mLoadedUserTime = in.readLong();
4876 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004877 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004878 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004879 mLastUserTime = 0;
4880 mLastSystemTime = 0;
4881 mLastForegroundTime = 0;
4882 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004883 mUnpluggedUserTime = in.readLong();
4884 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004885 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004886 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07004887
4888 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004889 int steps = getCpuSpeedSteps();
4890 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07004891 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004892 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004893 mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004894 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004895 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004896
Dianne Hackborn287952c2010-09-22 22:34:31 -07004897 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004898 }
4899
4900 public BatteryStatsImpl getBatteryStats() {
4901 return BatteryStatsImpl.this;
4902 }
4903
4904 public void addCpuTimeLocked(int utime, int stime) {
4905 mUserTime += utime;
4906 mSystemTime += stime;
4907 }
4908
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004909 public void addForegroundTimeLocked(long ttime) {
4910 mForegroundTime += ttime;
4911 }
4912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004913 public void incStartsLocked() {
4914 mStarts++;
4915 }
4916
4917 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08004918 public boolean isActive() {
4919 return mActive;
4920 }
4921
4922 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004923 public long getUserTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07004924 long val = mUserTime;
4925 if (which == STATS_CURRENT) {
4926 val -= mLoadedUserTime;
4927 } else if (which == STATS_SINCE_UNPLUGGED) {
4928 val -= mUnpluggedUserTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004929 }
4930 return val;
4931 }
4932
4933 @Override
4934 public long getSystemTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07004935 long val = mSystemTime;
4936 if (which == STATS_CURRENT) {
4937 val -= mLoadedSystemTime;
4938 } else if (which == STATS_SINCE_UNPLUGGED) {
4939 val -= mUnpluggedSystemTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004940 }
4941 return val;
4942 }
4943
4944 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004945 public long getForegroundTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07004946 long val = mForegroundTime;
4947 if (which == STATS_CURRENT) {
4948 val -= mLoadedForegroundTime;
4949 } else if (which == STATS_SINCE_UNPLUGGED) {
4950 val -= mUnpluggedForegroundTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004951 }
4952 return val;
4953 }
4954
4955 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004956 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07004957 int val = mStarts;
4958 if (which == STATS_CURRENT) {
4959 val -= mLoadedStarts;
4960 } else if (which == STATS_SINCE_UNPLUGGED) {
4961 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 }
4963 return val;
4964 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004965
4966 /* Called by ActivityManagerService when CPU times are updated. */
4967 public void addSpeedStepTimes(long[] values) {
4968 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004969 long amt = values[i];
4970 if (amt != 0) {
4971 SamplingCounter c = mSpeedBins[i];
4972 if (c == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004973 mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004974 }
4975 c.addCountAtomic(values[i]);
4976 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004977 }
4978 }
4979
4980 @Override
4981 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
4982 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004983 SamplingCounter c = mSpeedBins[speedStep];
4984 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07004985 } else {
4986 return 0;
4987 }
4988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004989 }
4990
4991 /**
4992 * The statistics associated with a particular package.
4993 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004994 public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004995 /**
4996 * Number of times this package has done something that could wake up the
4997 * device from sleep.
4998 */
4999 int mWakeups;
5000
5001 /**
5002 * Number of things that could wake up the device loaded from a
5003 * previous save.
5004 */
5005 int mLoadedWakeups;
5006
5007 /**
5008 * Number of things that could wake up the device as of the
5009 * last run.
5010 */
5011 int mLastWakeups;
5012
5013 /**
5014 * Number of things that could wake up the device as of the
5015 * last run.
5016 */
5017 int mUnpluggedWakeups;
5018
5019 /**
5020 * The statics we have collected for this package's services.
5021 */
5022 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
5023
5024 Pkg() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005025 mOnBatteryScreenOffTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005026 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005027
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005028 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005029 mUnpluggedWakeups = mWakeups;
5030 }
5031
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005032 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005033 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005034
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005035 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005036 mOnBatteryScreenOffTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005037 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005039 void readFromParcelLocked(Parcel in) {
5040 mWakeups = in.readInt();
5041 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005042 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005043 mUnpluggedWakeups = in.readInt();
5044
5045 int numServs = in.readInt();
5046 mServiceStats.clear();
5047 for (int m = 0; m < numServs; m++) {
5048 String serviceName = in.readString();
5049 Uid.Pkg.Serv serv = new Serv();
5050 mServiceStats.put(serviceName, serv);
5051
5052 serv.readFromParcelLocked(in);
5053 }
5054 }
5055
5056 void writeToParcelLocked(Parcel out) {
5057 out.writeInt(mWakeups);
5058 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005059 out.writeInt(mUnpluggedWakeups);
5060
5061 out.writeInt(mServiceStats.size());
5062 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
5063 out.writeString(servEntry.getKey());
5064 Uid.Pkg.Serv serv = servEntry.getValue();
5065
5066 serv.writeToParcelLocked(out);
5067 }
5068 }
5069
5070 @Override
5071 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
5072 return mServiceStats;
5073 }
5074
5075 @Override
5076 public int getWakeups(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07005077 int val = mWakeups;
5078 if (which == STATS_CURRENT) {
5079 val -= mLoadedWakeups;
5080 } else if (which == STATS_SINCE_UNPLUGGED) {
5081 val -= mUnpluggedWakeups;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005082 }
5083
5084 return val;
5085 }
5086
5087 /**
5088 * The statistics associated with a particular service.
5089 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005090 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005091 /**
5092 * Total time (ms in battery uptime) the service has been left started.
5093 */
5094 long mStartTime;
5095
5096 /**
5097 * If service has been started and not yet stopped, this is
5098 * when it was started.
5099 */
5100 long mRunningSince;
5101
5102 /**
5103 * True if we are currently running.
5104 */
5105 boolean mRunning;
5106
5107 /**
5108 * Total number of times startService() has been called.
5109 */
5110 int mStarts;
5111
5112 /**
5113 * Total time (ms in battery uptime) the service has been left launched.
5114 */
5115 long mLaunchedTime;
5116
5117 /**
5118 * If service has been launched and not yet exited, this is
5119 * when it was launched (ms in battery uptime).
5120 */
5121 long mLaunchedSince;
5122
5123 /**
5124 * True if we are currently launched.
5125 */
5126 boolean mLaunched;
5127
5128 /**
5129 * Total number times the service has been launched.
5130 */
5131 int mLaunches;
5132
5133 /**
5134 * The amount of time spent started loaded from a previous save
5135 * (ms in battery uptime).
5136 */
5137 long mLoadedStartTime;
5138
5139 /**
5140 * The number of starts loaded from a previous save.
5141 */
5142 int mLoadedStarts;
5143
5144 /**
5145 * The number of launches loaded from a previous save.
5146 */
5147 int mLoadedLaunches;
5148
5149 /**
5150 * The amount of time spent started as of the last run (ms
5151 * in battery uptime).
5152 */
5153 long mLastStartTime;
5154
5155 /**
5156 * The number of starts as of the last run.
5157 */
5158 int mLastStarts;
5159
5160 /**
5161 * The number of launches as of the last run.
5162 */
5163 int mLastLaunches;
5164
5165 /**
5166 * The amount of time spent started when last unplugged (ms
5167 * in battery uptime).
5168 */
5169 long mUnpluggedStartTime;
5170
5171 /**
5172 * The number of starts when last unplugged.
5173 */
5174 int mUnpluggedStarts;
5175
5176 /**
5177 * The number of launches when last unplugged.
5178 */
5179 int mUnpluggedLaunches;
5180
5181 Serv() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005182 mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005183 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005184
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005185 public void onTimeStarted(long elapsedRealtime, long baseUptime,
5186 long baseRealtime) {
5187 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005188 mUnpluggedStarts = mStarts;
5189 mUnpluggedLaunches = mLaunches;
5190 }
5191
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005192 public void onTimeStopped(long elapsedRealtime, long baseUptime,
5193 long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005194 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005195
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005196 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005197 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005198 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005200 void readFromParcelLocked(Parcel in) {
5201 mStartTime = in.readLong();
5202 mRunningSince = in.readLong();
5203 mRunning = in.readInt() != 0;
5204 mStarts = in.readInt();
5205 mLaunchedTime = in.readLong();
5206 mLaunchedSince = in.readLong();
5207 mLaunched = in.readInt() != 0;
5208 mLaunches = in.readInt();
5209 mLoadedStartTime = in.readLong();
5210 mLoadedStarts = in.readInt();
5211 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005212 mLastStartTime = 0;
5213 mLastStarts = 0;
5214 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005215 mUnpluggedStartTime = in.readLong();
5216 mUnpluggedStarts = in.readInt();
5217 mUnpluggedLaunches = in.readInt();
5218 }
5219
5220 void writeToParcelLocked(Parcel out) {
5221 out.writeLong(mStartTime);
5222 out.writeLong(mRunningSince);
5223 out.writeInt(mRunning ? 1 : 0);
5224 out.writeInt(mStarts);
5225 out.writeLong(mLaunchedTime);
5226 out.writeLong(mLaunchedSince);
5227 out.writeInt(mLaunched ? 1 : 0);
5228 out.writeInt(mLaunches);
5229 out.writeLong(mLoadedStartTime);
5230 out.writeInt(mLoadedStarts);
5231 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005232 out.writeLong(mUnpluggedStartTime);
5233 out.writeInt(mUnpluggedStarts);
5234 out.writeInt(mUnpluggedLaunches);
5235 }
5236
5237 long getLaunchTimeToNowLocked(long batteryUptime) {
5238 if (!mLaunched) return mLaunchedTime;
5239 return mLaunchedTime + batteryUptime - mLaunchedSince;
5240 }
5241
5242 long getStartTimeToNowLocked(long batteryUptime) {
5243 if (!mRunning) return mStartTime;
5244 return mStartTime + batteryUptime - mRunningSince;
5245 }
5246
5247 public void startLaunchedLocked() {
5248 if (!mLaunched) {
5249 mLaunches++;
5250 mLaunchedSince = getBatteryUptimeLocked();
5251 mLaunched = true;
5252 }
5253 }
5254
5255 public void stopLaunchedLocked() {
5256 if (mLaunched) {
5257 long time = getBatteryUptimeLocked() - mLaunchedSince;
5258 if (time > 0) {
5259 mLaunchedTime += time;
5260 } else {
5261 mLaunches--;
5262 }
5263 mLaunched = false;
5264 }
5265 }
5266
5267 public void startRunningLocked() {
5268 if (!mRunning) {
5269 mStarts++;
5270 mRunningSince = getBatteryUptimeLocked();
5271 mRunning = true;
5272 }
5273 }
5274
5275 public void stopRunningLocked() {
5276 if (mRunning) {
5277 long time = getBatteryUptimeLocked() - mRunningSince;
5278 if (time > 0) {
5279 mStartTime += time;
5280 } else {
5281 mStarts--;
5282 }
5283 mRunning = false;
5284 }
5285 }
5286
5287 public BatteryStatsImpl getBatteryStats() {
5288 return BatteryStatsImpl.this;
5289 }
5290
5291 @Override
5292 public int getLaunches(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07005293 int val = mLaunches;
5294 if (which == STATS_CURRENT) {
5295 val -= mLoadedLaunches;
5296 } else if (which == STATS_SINCE_UNPLUGGED) {
5297 val -= mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005299 return val;
5300 }
5301
5302 @Override
5303 public long getStartTime(long now, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07005304 long val = getStartTimeToNowLocked(now);
5305 if (which == STATS_CURRENT) {
5306 val -= mLoadedStartTime;
5307 } else if (which == STATS_SINCE_UNPLUGGED) {
5308 val -= mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005309 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005310 return val;
5311 }
5312
5313 @Override
5314 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07005315 int val = mStarts;
5316 if (which == STATS_CURRENT) {
5317 val -= mLoadedStarts;
5318 } else if (which == STATS_SINCE_UNPLUGGED) {
5319 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005320 }
5321
5322 return val;
5323 }
5324 }
5325
5326 public BatteryStatsImpl getBatteryStats() {
5327 return BatteryStatsImpl.this;
5328 }
5329
5330 public void incWakeupsLocked() {
5331 mWakeups++;
5332 }
5333
5334 final Serv newServiceStatsLocked() {
5335 return new Serv();
5336 }
5337 }
5338
5339 /**
5340 * Retrieve the statistics object for a particular process, creating
5341 * if needed.
5342 */
5343 public Proc getProcessStatsLocked(String name) {
5344 Proc ps = mProcessStats.get(name);
5345 if (ps == null) {
5346 ps = new Proc();
5347 mProcessStats.put(name, ps);
5348 }
5349
5350 return ps;
5351 }
5352
Dianne Hackbornb5e31652010-09-07 12:13:55 -07005353 public SparseArray<? extends Pid> getPidStats() {
5354 return mPids;
5355 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005356
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005357 public Pid getPidStatsLocked(int pid) {
5358 Pid p = mPids.get(pid);
5359 if (p == null) {
5360 p = new Pid();
5361 mPids.put(pid, p);
5362 }
5363 return p;
5364 }
5365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005366 /**
5367 * Retrieve the statistics object for a particular service, creating
5368 * if needed.
5369 */
5370 public Pkg getPackageStatsLocked(String name) {
5371 Pkg ps = mPackageStats.get(name);
5372 if (ps == null) {
5373 ps = new Pkg();
5374 mPackageStats.put(name, ps);
5375 }
5376
5377 return ps;
5378 }
5379
5380 /**
5381 * Retrieve the statistics object for a particular service, creating
5382 * if needed.
5383 */
5384 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
5385 Pkg ps = getPackageStatsLocked(pkg);
5386 Pkg.Serv ss = ps.mServiceStats.get(serv);
5387 if (ss == null) {
5388 ss = ps.newServiceStatsLocked();
5389 ps.mServiceStats.put(serv, ss);
5390 }
5391
5392 return ss;
5393 }
5394
Evan Millarc64edde2009-04-18 12:26:32 -07005395 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005396 Wakelock wl = mWakelockStats.get(name);
5397 if (wl == null) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07005398 final int N = mWakelockStats.size();
Dianne Hackbornaf17baa2013-05-09 15:27:47 -07005399 if (N > MAX_WAKELOCKS_PER_UID) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005400 name = BATCHED_WAKELOCK_NAME;
5401 wl = mWakelockStats.get(name);
5402 }
5403 if (wl == null) {
5404 wl = new Wakelock();
5405 mWakelockStats.put(name, wl);
5406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 }
Evan Millarc64edde2009-04-18 12:26:32 -07005408 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005409 switch (type) {
5410 case WAKE_TYPE_PARTIAL:
5411 t = wl.mTimerPartial;
5412 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005413 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005414 mPartialTimers, mOnBatteryScreenOffTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005415 wl.mTimerPartial = t;
5416 }
5417 return t;
5418 case WAKE_TYPE_FULL:
5419 t = wl.mTimerFull;
5420 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005421 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005422 mFullTimers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005423 wl.mTimerFull = t;
5424 }
5425 return t;
5426 case WAKE_TYPE_WINDOW:
5427 t = wl.mTimerWindow;
5428 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005429 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005430 mWindowTimers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005431 wl.mTimerWindow = t;
5432 }
5433 return t;
5434 default:
5435 throw new IllegalArgumentException("type=" + type);
5436 }
5437 }
5438
Evan Millarc64edde2009-04-18 12:26:32 -07005439 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005440 Sensor se = mSensorStats.get(sensor);
5441 if (se == null) {
5442 if (!create) {
5443 return null;
5444 }
5445 se = new Sensor(sensor);
5446 mSensorStats.put(sensor, se);
5447 }
Evan Millarc64edde2009-04-18 12:26:32 -07005448 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005449 if (t != null) {
5450 return t;
5451 }
Evan Millarc64edde2009-04-18 12:26:32 -07005452 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005453 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07005454 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005455 mSensorTimers.put(sensor, timers);
5456 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005457 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005458 se.mTimer = t;
5459 return t;
5460 }
5461
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005462 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005463 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005464 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005465 t.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07005467 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005468 Pid p = getPidStatsLocked(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005469 if (p.mWakeNesting++ == 0) {
5470 p.mWakeStartMs = elapsedRealtimeMs;
Dianne Hackbornb8071d792010-09-09 16:45:15 -07005471 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005472 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005473 }
5474
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005475 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005476 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005477 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005478 t.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005479 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07005480 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005481 Pid p = mPids.get(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005482 if (p != null && p.mWakeNesting > 0) {
5483 if (p.mWakeNesting-- == 1) {
5484 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
5485 p.mWakeStartMs = 0;
5486 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005487 }
5488 }
5489 }
5490
5491 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
5492 Proc p = getProcessStatsLocked(proc);
5493 if (p != null) {
5494 p.addExcessiveWake(overTime, usedTime);
5495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005496 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005497
Dianne Hackborn287952c2010-09-22 22:34:31 -07005498 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
5499 Proc p = getProcessStatsLocked(proc);
5500 if (p != null) {
5501 p.addExcessiveCpu(overTime, usedTime);
5502 }
5503 }
5504
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005505 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005506 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005507 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005508 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005510 }
5511
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005512 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005513 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07005514 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005515 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005516 t.stopRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005519
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005520 public void noteStartGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005521 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005522 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005523 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005524 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005525 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005526
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005527 public void noteStopGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005528 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005529 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005530 t.stopRunningLocked(elapsedRealtimeMs);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005531 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005532 }
5533
5534 public BatteryStatsImpl getBatteryStats() {
5535 return BatteryStatsImpl.this;
5536 }
5537 }
5538
Jeff Brown6f357d32014-01-15 20:40:55 -08005539 public BatteryStatsImpl(String filename, Handler handler) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005540 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Jeff Brown6f357d32014-01-15 20:40:55 -08005541 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005542 mStartCount++;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005543 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005544 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005545 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005546 }
Dianne Hackborn29325132014-05-21 15:01:03 -07005547 mInteractiveTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005548 mLowPowerModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase);
5549 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase);
Wink Saville52840902011-02-18 12:40:47 -08005550 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005551 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null,
5552 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005553 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005554 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005555 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005556 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null,
5557 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005558 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005559 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005560 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
5561 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005562 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005563 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase);
5564 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005565 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005566 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
5567 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005568 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase);
5569 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005570 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005571 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005572 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005573 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005574 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005575 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, null, mOnBatteryTimeBase);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08005576 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005577 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
5578 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005579 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005580 long uptime = SystemClock.uptimeMillis() * 1000;
5581 long realtime = SystemClock.elapsedRealtime() * 1000;
5582 initTimes(uptime, realtime);
Evan Millar633a1742009-04-02 16:36:33 -07005583 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005584 mDischargeUnplugLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07005585 mDischargePlugLevel = -1;
Evan Millar633a1742009-04-02 16:36:33 -07005586 mDischargeCurrentLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07005587 mCurrentBatteryLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005588 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005589 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005590 }
5591
5592 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005593 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005594 mHandler = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005595 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005596 readFromParcel(p);
5597 }
5598
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005599 public void setCallback(BatteryCallback cb) {
5600 mCallback = cb;
5601 }
5602
Amith Yamasanie43530a2009-08-21 13:11:37 -07005603 public void setNumSpeedSteps(int steps) {
5604 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
5605 }
5606
Amith Yamasanif37447b2009-10-08 18:28:01 -07005607 public void setRadioScanningTimeout(long timeout) {
5608 if (mPhoneSignalScanningTimer != null) {
5609 mPhoneSignalScanningTimer.setTimeout(timeout);
5610 }
5611 }
5612
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005613 @Override
5614 public boolean startIteratingOldHistoryLocked() {
5615 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
5616 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005617 if ((mHistoryIterator = mHistory) == null) {
5618 return false;
5619 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005620 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005621 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005622 mReadOverflow = false;
5623 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005624 return true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005625 }
5626
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005627 @Override
5628 public boolean getNextOldHistoryLocked(HistoryItem out) {
5629 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
5630 if (!end) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005631 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005632 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005633 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005634 HistoryItem cur = mHistoryIterator;
5635 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005636 if (!mReadOverflow && !end) {
5637 Slog.w(TAG, "Old history ends before new history!");
5638 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005639 return false;
5640 }
5641 out.setTo(cur);
5642 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005643 if (!mReadOverflow) {
5644 if (end) {
5645 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005646 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn8c841092013-06-24 13:46:13 -07005647 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005648 pw.println("Histories differ!");
5649 pw.println("Old history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07005650 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005651 pw.println("New history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07005652 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false,
5653 true);
Dianne Hackborn8c841092013-06-24 13:46:13 -07005654 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005655 }
5656 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005657 return true;
5658 }
5659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005660 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005661 public void finishIteratingOldHistoryLocked() {
5662 mIteratingHistory = false;
5663 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005664 mHistoryIterator = null;
5665 }
5666
5667 public int getHistoryTotalSize() {
5668 return MAX_HISTORY_BUFFER;
5669 }
5670
5671 public int getHistoryUsedSize() {
5672 return mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005673 }
5674
5675 @Override
5676 public boolean startIteratingHistoryLocked() {
5677 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
5678 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005679 if (mHistoryBuffer.dataSize() <= 0) {
5680 return false;
5681 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005682 mHistoryBuffer.setDataPosition(0);
5683 mReadOverflow = false;
5684 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005685 mReadHistoryStrings = new String[mHistoryTagPool.size()];
5686 mReadHistoryUids = new int[mHistoryTagPool.size()];
5687 mReadHistoryChars = 0;
5688 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
5689 final HistoryTag tag = ent.getKey();
5690 final int idx = ent.getValue();
5691 mReadHistoryStrings[idx] = tag.string;
5692 mReadHistoryUids[idx] = tag.uid;
5693 mReadHistoryChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08005694 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005695 return true;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005696 }
5697
5698 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08005699 public int getHistoryStringPoolSize() {
5700 return mReadHistoryStrings.length;
5701 }
5702
5703 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005704 public int getHistoryStringPoolBytes() {
5705 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
5706 // Each string character is 2 bytes.
5707 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
5708 }
5709
5710 @Override
5711 public String getHistoryTagPoolString(int index) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005712 return mReadHistoryStrings[index];
5713 }
5714
5715 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005716 public int getHistoryTagPoolUid(int index) {
5717 return mReadHistoryUids[index];
5718 }
5719
5720 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005721 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005722 final int pos = mHistoryBuffer.dataPosition();
5723 if (pos == 0) {
5724 out.clear();
5725 }
5726 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005727 if (end) {
5728 return false;
5729 }
5730
Dianne Hackborn99009ea2014-04-18 16:23:42 -07005731 final long lastRealtime = out.time;
5732 final long lastWalltime = out.currentTime;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005733 readHistoryDelta(mHistoryBuffer, out);
Dianne Hackborn37de0982014-05-09 09:32:18 -07005734 if (out.cmd != HistoryItem.CMD_CURRENT_TIME
5735 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
Dianne Hackborn99009ea2014-04-18 16:23:42 -07005736 out.currentTime = lastWalltime + (out.time - lastRealtime);
5737 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005738 return true;
5739 }
5740
5741 @Override
5742 public void finishIteratingHistoryLocked() {
5743 mIteratingHistory = false;
5744 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn099bc622014-01-22 13:39:16 -08005745 mReadHistoryStrings = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005746 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005747
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005748 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07005749 public long getHistoryBaseTime() {
5750 return mHistoryBaseTime;
5751 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005752
Dianne Hackbornb5e31652010-09-07 12:13:55 -07005753 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005754 public int getStartCount() {
5755 return mStartCount;
5756 }
5757
5758 public boolean isOnBattery() {
5759 return mOnBattery;
5760 }
5761
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005762 public boolean isScreenOn() {
Jeff Browne95c3cd2014-05-02 16:59:26 -07005763 return mScreenState == Display.STATE_ON;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005764 }
5765
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005766 void initTimes(long uptime, long realtime) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08005767 mStartClockTime = System.currentTimeMillis();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005768 mOnBatteryTimeBase.init(uptime, realtime);
5769 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
Dianne Hackborn4590e522014-03-24 13:36:46 -07005770 mRealtime = 0;
5771 mUptime = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005772 mRealtimeStart = realtime;
Dianne Hackborn4590e522014-03-24 13:36:46 -07005773 mUptimeStart = uptime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005774 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005775
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005776 void initDischarge() {
5777 mLowDischargeAmountSinceCharge = 0;
5778 mHighDischargeAmountSinceCharge = 0;
5779 mDischargeAmountScreenOn = 0;
5780 mDischargeAmountScreenOnSinceCharge = 0;
5781 mDischargeAmountScreenOff = 0;
5782 mDischargeAmountScreenOffSinceCharge = 0;
Dianne Hackborn260c5022014-04-29 11:23:16 -07005783 mLastDischargeStepTime = -1;
5784 mNumDischargeStepDurations = 0;
5785 mLastChargeStepTime = -1;
5786 mNumChargeStepDurations = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005787 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005788
5789 public void resetAllStatsCmdLocked() {
5790 resetAllStatsLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07005791 final long mSecUptime = SystemClock.uptimeMillis();
5792 long uptime = mSecUptime * 1000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005793 long mSecRealtime = SystemClock.elapsedRealtime();
5794 long realtime = mSecRealtime * 1000;
5795 mDischargeStartLevel = mHistoryCur.batteryLevel;
5796 pullPendingStateUpdatesLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07005797 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07005798 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
5799 = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005800 mOnBatteryTimeBase.reset(uptime, realtime);
5801 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
5802 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07005803 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005804 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
5805 mDischargeScreenOffUnplugLevel = 0;
5806 } else {
5807 mDischargeScreenOnUnplugLevel = 0;
5808 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
5809 }
5810 mDischargeAmountScreenOn = 0;
5811 mDischargeAmountScreenOff = 0;
5812 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07005813 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005814 }
5815
5816 private void resetAllStatsLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005817 mStartCount = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005818 initTimes(SystemClock.uptimeMillis() * 1000, SystemClock.elapsedRealtime() * 1000);
5819 mScreenOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005820 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005821 mScreenBrightnessTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005822 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07005823 mInteractiveTimer.reset(false);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005824 mLowPowerModeEnabledTimer.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005825 mPhoneOnTimer.reset(false);
5826 mAudioOnTimer.reset(false);
5827 mVideoOnTimer.reset(false);
Wink Saville52840902011-02-18 12:40:47 -08005828 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005829 mPhoneSignalStrengthsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005830 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005831 mPhoneSignalScanningTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005832 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005833 mPhoneDataConnectionsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005834 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005835 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005836 mNetworkByteActivityCounters[i].reset(false);
5837 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005838 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005839 mMobileRadioActiveTimer.reset(false);
5840 mMobileRadioActivePerAppTimer.reset(false);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005841 mMobileRadioActiveAdjustedTime.reset(false);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005842 mMobileRadioActiveUnknownTime.reset(false);
5843 mMobileRadioActiveUnknownCount.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005844 mWifiOnTimer.reset(false);
5845 mGlobalWifiRunningTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005846 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005847 mWifiStateTimer[i].reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005848 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005849 mBluetoothOnTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005850 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005851 mBluetoothStateTimer[i].reset(false);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08005852 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005853
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005854 for (int i=0; i<mUidStats.size(); i++) {
5855 if (mUidStats.valueAt(i).reset()) {
5856 mUidStats.remove(mUidStats.keyAt(i));
5857 i--;
5858 }
5859 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005860
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005861 if (mKernelWakelockStats.size() > 0) {
5862 for (SamplingTimer timer : mKernelWakelockStats.values()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005863 mOnBatteryScreenOffTimeBase.remove(timer);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005864 }
5865 mKernelWakelockStats.clear();
5866 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005867
5868 if (mWakeupReasonStats.size() > 0) {
5869 for (LongSamplingCounter timer : mWakeupReasonStats.values()) {
5870 mOnBatteryScreenOffTimeBase.remove(timer);
5871 }
5872 mWakeupReasonStats.clear();
5873 }
5874
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005875 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005876
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005877 clearHistoryLocked();
5878 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005879
Dianne Hackborn40c87252014-03-19 16:55:40 -07005880 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005881 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07005882 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005883 if (active == null) {
5884 continue;
5885 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07005886 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
5887 SparseIntArray uids = ent.getValue();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005888 for (int j=0; j<uids.size(); j++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07005889 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
5890 uids.keyAt(j));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005891 }
5892 }
5893 }
5894 }
5895
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005896 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005897 if (oldScreenOn) {
5898 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
5899 if (diff > 0) {
5900 mDischargeAmountScreenOn += diff;
5901 mDischargeAmountScreenOnSinceCharge += diff;
5902 }
5903 } else {
5904 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
5905 if (diff > 0) {
5906 mDischargeAmountScreenOff += diff;
5907 mDischargeAmountScreenOffSinceCharge += diff;
5908 }
5909 }
5910 if (newScreenOn) {
5911 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
5912 mDischargeScreenOffUnplugLevel = 0;
5913 } else {
5914 mDischargeScreenOnUnplugLevel = 0;
5915 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
5916 }
5917 }
5918
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005919 public void pullPendingStateUpdatesLocked() {
5920 updateKernelWakelocksLocked();
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005921 updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
Dianne Hackborn77b987f2014-02-26 16:20:52 -08005922 if (mOnBatteryInternal) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07005923 final boolean screenOn = mScreenState == Display.STATE_ON;
5924 updateDischargeScreenLevelsLocked(screenOn, screenOn);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08005925 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005926 }
5927
Dianne Hackborn40c87252014-03-19 16:55:40 -07005928 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
5929 final int oldStatus, final int level) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005930 boolean doWrite = false;
5931 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
5932 m.arg1 = onBattery ? 1 : 0;
5933 mHandler.sendMessage(m);
5934 mOnBattery = mOnBatteryInternal = onBattery;
5935
Dianne Hackborn40c87252014-03-19 16:55:40 -07005936 final long uptime = mSecUptime * 1000;
5937 final long realtime = mSecRealtime * 1000;
Jeff Browne95c3cd2014-05-02 16:59:26 -07005938 final boolean screenOn = mScreenState == Display.STATE_ON;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005939 if (onBattery) {
5940 // We will reset our status if we are unplugging after the
5941 // battery was last full, or the level is at 100, or
5942 // we have gone through a significant charge (from a very low
5943 // level to a now very high level).
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005944 boolean reset = false;
Dianne Hackborn9a755432014-05-15 17:05:22 -07005945 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005946 || level >= 90
Dianne Hackborn9a755432014-05-15 17:05:22 -07005947 || (mDischargeCurrentLevel < 20 && level >= 80))) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005948 doWrite = true;
5949 resetAllStatsLocked();
5950 mDischargeStartLevel = level;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005951 reset = true;
Dianne Hackborn260c5022014-04-29 11:23:16 -07005952 mNumDischargeStepDurations = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005953 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07005954 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07005955 mMinDischargeStepLevel = level;
Dianne Hackborn260c5022014-04-29 11:23:16 -07005956 mLastDischargeStepTime = -1;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005957 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005958 mHistoryCur.batteryLevel = (byte)level;
5959 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
5960 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
5961 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005962 if (reset) {
5963 mRecordingHistory = true;
5964 startRecordingHistory(mSecRealtime, mSecUptime, reset);
5965 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07005966 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005967 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
Jeff Browne95c3cd2014-05-02 16:59:26 -07005968 if (screenOn) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005969 mDischargeScreenOnUnplugLevel = level;
5970 mDischargeScreenOffUnplugLevel = 0;
5971 } else {
5972 mDischargeScreenOnUnplugLevel = 0;
5973 mDischargeScreenOffUnplugLevel = level;
5974 }
5975 mDischargeAmountScreenOn = 0;
5976 mDischargeAmountScreenOff = 0;
Jeff Browne95c3cd2014-05-02 16:59:26 -07005977 updateTimeBasesLocked(true, !screenOn, uptime, realtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005978 } else {
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005979 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005980 mHistoryCur.batteryLevel = (byte)level;
5981 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
5982 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
5983 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005984 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07005985 mDischargeCurrentLevel = mDischargePlugLevel = level;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005986 if (level < mDischargeUnplugLevel) {
5987 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
5988 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
5989 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07005990 updateDischargeScreenLevelsLocked(screenOn, screenOn);
5991 updateTimeBasesLocked(false, !screenOn, uptime, realtime);
Dianne Hackborn260c5022014-04-29 11:23:16 -07005992 mNumChargeStepDurations = 0;
5993 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07005994 mMaxChargeStepLevel = level;
Dianne Hackborn260c5022014-04-29 11:23:16 -07005995 mLastChargeStepTime = -1;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005996 }
5997 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
5998 if (mFile != null) {
5999 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006000 }
6001 }
6002 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006003
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006004 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
6005 boolean reset) {
6006 mRecordingHistory = true;
6007 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn37de0982014-05-09 09:32:18 -07006008 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
6009 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006010 mHistoryCur);
6011 mHistoryCur.currentTime = 0;
6012 if (reset) {
6013 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
6014 }
6015 }
6016
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006017 // This should probably be exposed in the API, though it's not critical
6018 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006019
Dianne Hackborn260c5022014-04-29 11:23:16 -07006020 private static int addLevelSteps(long[] steps, int stepCount, long lastStepTime,
6021 int numStepLevels, long elapsedRealtime) {
6022 if (lastStepTime >= 0 && numStepLevels > 0) {
6023 long duration = elapsedRealtime - lastStepTime;
6024 for (int i=0; i<numStepLevels; i++) {
6025 System.arraycopy(steps, 0, steps, 1, steps.length-1);
6026 long thisDuration = duration / (numStepLevels-i);
6027 duration -= thisDuration;
6028 steps[0] = thisDuration;
6029 }
6030 stepCount += numStepLevels;
6031 if (stepCount > steps.length) {
6032 stepCount = steps.length;
6033 }
6034 }
6035 return stepCount;
6036 }
6037
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006038 public void setBatteryState(int status, int health, int plugType, int level,
6039 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006040 synchronized(this) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07006041 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
6042 final long uptime = SystemClock.uptimeMillis();
6043 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006044 int oldStatus = mHistoryCur.batteryStatus;
6045 if (!mHaveBatteryLevel) {
6046 mHaveBatteryLevel = true;
6047 // We start out assuming that the device is plugged in (not
6048 // on battery). If our first report is now that we are indeed
6049 // plugged in, then twiddle our state to correctly reflect that
6050 // since we won't be going through the full setOnBattery().
6051 if (onBattery == mOnBattery) {
6052 if (onBattery) {
6053 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
6054 } else {
6055 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
6056 }
6057 }
6058 oldStatus = status;
6059 }
6060 if (onBattery) {
6061 mDischargeCurrentLevel = level;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006062 if (!mRecordingHistory) {
6063 mRecordingHistory = true;
6064 startRecordingHistory(elapsedRealtime, uptime, true);
6065 }
6066 } else if (level < 96) {
6067 if (!mRecordingHistory) {
6068 mRecordingHistory = true;
6069 startRecordingHistory(elapsedRealtime, uptime, true);
6070 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006071 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006072 mCurrentBatteryLevel = level;
6073 if (mDischargePlugLevel < 0) {
6074 mDischargePlugLevel = level;
6075 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006076 if (onBattery != mOnBattery) {
6077 mHistoryCur.batteryLevel = (byte)level;
6078 mHistoryCur.batteryStatus = (byte)status;
6079 mHistoryCur.batteryHealth = (byte)health;
6080 mHistoryCur.batteryPlugType = (byte)plugType;
Sungmin Choic7e9e8b2013-01-16 12:57:36 +09006081 mHistoryCur.batteryTemperature = (short)temp;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006082 mHistoryCur.batteryVoltage = (char)volt;
Dianne Hackborn40c87252014-03-19 16:55:40 -07006083 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006084 } else {
6085 boolean changed = false;
6086 if (mHistoryCur.batteryLevel != level) {
6087 mHistoryCur.batteryLevel = (byte)level;
6088 changed = true;
6089 }
6090 if (mHistoryCur.batteryStatus != status) {
6091 mHistoryCur.batteryStatus = (byte)status;
6092 changed = true;
6093 }
6094 if (mHistoryCur.batteryHealth != health) {
6095 mHistoryCur.batteryHealth = (byte)health;
6096 changed = true;
6097 }
6098 if (mHistoryCur.batteryPlugType != plugType) {
6099 mHistoryCur.batteryPlugType = (byte)plugType;
6100 changed = true;
6101 }
6102 if (temp >= (mHistoryCur.batteryTemperature+10)
6103 || temp <= (mHistoryCur.batteryTemperature-10)) {
Sungmin Choic7e9e8b2013-01-16 12:57:36 +09006104 mHistoryCur.batteryTemperature = (short)temp;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006105 changed = true;
6106 }
6107 if (volt > (mHistoryCur.batteryVoltage+20)
6108 || volt < (mHistoryCur.batteryVoltage-20)) {
6109 mHistoryCur.batteryVoltage = (char)volt;
6110 changed = true;
6111 }
6112 if (changed) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07006113 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006114 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07006115 if (onBattery) {
Dianne Hackborn29325132014-05-21 15:01:03 -07006116 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07006117 mNumDischargeStepDurations = addLevelSteps(mDischargeStepDurations,
6118 mNumDischargeStepDurations, mLastDischargeStepTime,
6119 mLastDischargeStepLevel - level, elapsedRealtime);
6120 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07006121 mMinDischargeStepLevel = level;
Dianne Hackborn260c5022014-04-29 11:23:16 -07006122 mLastDischargeStepTime = elapsedRealtime;
6123 }
6124 } else {
Dianne Hackborn29325132014-05-21 15:01:03 -07006125 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07006126 mNumChargeStepDurations = addLevelSteps(mChargeStepDurations,
6127 mNumChargeStepDurations, mLastChargeStepTime,
6128 level - mLastChargeStepLevel, elapsedRealtime);
6129 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07006130 mMaxChargeStepLevel = level;
Dianne Hackborn260c5022014-04-29 11:23:16 -07006131 mLastChargeStepTime = elapsedRealtime;
6132 }
6133 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006134 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006135 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
6136 // We don't record history while we are plugged in and fully charged.
6137 // The next time we are unplugged, history will be cleared.
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08006138 mRecordingHistory = DEBUG;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006139 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006140 }
Evan Millar633a1742009-04-02 16:36:33 -07006141 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006142
Evan Millarc64edde2009-04-18 12:26:32 -07006143 public void updateKernelWakelocksLocked() {
6144 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006145
Marco Nelissend8593312009-04-30 14:45:06 -07006146 if (m == null) {
6147 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006148 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07006149 return;
6150 }
6151
Evan Millarc64edde2009-04-18 12:26:32 -07006152 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
6153 String name = ent.getKey();
6154 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006155
Evan Millarc64edde2009-04-18 12:26:32 -07006156 SamplingTimer kwlt = mKernelWakelockStats.get(name);
6157 if (kwlt == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006158 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
6159 true /* track reported val */);
Evan Millarc64edde2009-04-18 12:26:32 -07006160 mKernelWakelockStats.put(name, kwlt);
6161 }
6162 kwlt.updateCurrentReportedCount(kws.mCount);
6163 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
6164 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
6165 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006166
Evan Millarc64edde2009-04-18 12:26:32 -07006167 if (m.size() != mKernelWakelockStats.size()) {
6168 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
6169 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
6170 SamplingTimer st = ent.getValue();
6171 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
6172 st.setStale();
6173 }
6174 }
6175 }
6176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006178 static final int NET_UPDATE_MOBILE = 1<<0;
6179 static final int NET_UPDATE_WIFI = 1<<1;
6180 static final int NET_UPDATE_ALL = 0xffff;
6181
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006182 private void updateNetworkActivityLocked(int which, long elapsedRealtimeMs) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006183 if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
6184
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006185 if ((which&NET_UPDATE_MOBILE) != 0 && mMobileIfaces.length > 0) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006186 final NetworkStats snapshot;
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006187 final NetworkStats last = mCurMobileSnapshot;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006188 try {
6189 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
6190 mMobileIfaces, NetworkStats.TAG_NONE, mLastMobileSnapshot);
6191 } catch (IOException e) {
6192 Log.wtf(TAG, "Failed to read mobile network stats", e);
6193 return;
6194 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006195
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006196 mCurMobileSnapshot = snapshot;
6197 mLastMobileSnapshot = last;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006198
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006199 if (mOnBatteryInternal) {
6200 final NetworkStats delta = NetworkStats.subtract(snapshot, last,
6201 null, null, mTmpNetworkStats);
6202 mTmpNetworkStats = delta;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006203
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006204 long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked(
6205 elapsedRealtimeMs);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006206 long totalPackets = delta.getTotalPackets();
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006207
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006208 final int size = delta.size();
6209 for (int i = 0; i < size; i++) {
6210 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006211
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006212 if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006213
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006214 final Uid u = getUidStatsLocked(mapUid(entry.uid));
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006215 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
6216 entry.rxPackets);
6217 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
6218 entry.txPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006219
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006220 if (radioTime > 0) {
6221 // Distribute total radio active time in to this app.
6222 long appPackets = entry.rxPackets + entry.txPackets;
6223 long appRadioTime = (radioTime*appPackets)/totalPackets;
6224 u.noteMobileRadioActiveTimeLocked(appRadioTime);
6225 // Remove this app from the totals, so that we don't lose any time
6226 // due to rounding.
6227 radioTime -= appRadioTime;
6228 totalPackets -= appPackets;
6229 }
6230
6231 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
6232 entry.rxBytes);
6233 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
6234 entry.txBytes);
6235 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
6236 entry.rxPackets);
6237 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
6238 entry.txPackets);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006239 }
6240
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006241 if (radioTime > 0) {
6242 // Whoops, there is some radio time we can't blame on an app!
6243 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
6244 mMobileRadioActiveUnknownCount.addCountLocked(1);
6245 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006246 }
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006247 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006248
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006249 if ((which&NET_UPDATE_WIFI) != 0 && mWifiIfaces.length > 0) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006250 final NetworkStats snapshot;
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006251 final NetworkStats last = mCurWifiSnapshot;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006252 try {
6253 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
6254 mWifiIfaces, NetworkStats.TAG_NONE, mLastWifiSnapshot);
6255 } catch (IOException e) {
6256 Log.wtf(TAG, "Failed to read wifi network stats", e);
6257 return;
6258 }
6259
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006260 mCurWifiSnapshot = snapshot;
6261 mLastWifiSnapshot = last;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006262
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006263 if (mOnBatteryInternal) {
6264 final NetworkStats delta = NetworkStats.subtract(snapshot, last,
6265 null, null, mTmpNetworkStats);
6266 mTmpNetworkStats = delta;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006267
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006268 final int size = delta.size();
6269 for (int i = 0; i < size; i++) {
6270 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006271
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006272 if (DEBUG) {
6273 final NetworkStats.Entry cur = snapshot.getValues(i, null);
6274 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
6275 + " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes
6276 + " tx=" + cur.txBytes);
6277 }
6278
6279 if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
6280
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006281 final Uid u = getUidStatsLocked(mapUid(entry.uid));
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006282 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
6283 entry.rxPackets);
6284 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
6285 entry.txPackets);
6286
6287 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
6288 entry.rxBytes);
6289 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
6290 entry.txBytes);
6291 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
6292 entry.rxPackets);
6293 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
6294 entry.txPackets);
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006295 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006296 }
6297 }
6298 }
6299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006300 public long getAwakeTimeBattery() {
6301 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
6302 }
6303
6304 public long getAwakeTimePlugged() {
6305 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
6306 }
6307
6308 @Override
6309 public long computeUptime(long curTime, int which) {
6310 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006311 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006312 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07006313 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006314 }
6315 return 0;
6316 }
6317
6318 @Override
6319 public long computeRealtime(long curTime, int which) {
6320 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006321 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006322 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07006323 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006324 }
6325 return 0;
6326 }
6327
6328 @Override
6329 public long computeBatteryUptime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006330 return mOnBatteryTimeBase.computeUptime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006331 }
6332
6333 @Override
6334 public long computeBatteryRealtime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006335 return mOnBatteryTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006336 }
6337
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006338 @Override
6339 public long computeBatteryScreenOffUptime(long curTime, int which) {
6340 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
6341 }
6342
6343 @Override
6344 public long computeBatteryScreenOffRealtime(long curTime, int which) {
6345 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006346 }
6347
Dianne Hackborn260c5022014-04-29 11:23:16 -07006348 private long computeTimePerLevel(long[] steps, int numSteps) {
6349 // For now we'll do a simple average across all steps.
6350 if (numSteps <= 0) {
6351 return -1;
6352 }
6353 long total = 0;
6354 for (int i=0; i<numSteps; i++) {
6355 total += steps[i];
6356 }
6357 return total / numSteps;
6358 /*
6359 long[] buckets = new long[numSteps];
6360 int numBuckets = 0;
6361 int numToAverage = 4;
6362 int i = 0;
6363 while (i < numSteps) {
6364 long totalTime = 0;
6365 int num = 0;
6366 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
6367 totalTime += steps[i+j];
6368 num++;
6369 }
6370 buckets[numBuckets] = totalTime / num;
6371 numBuckets++;
6372 numToAverage *= 2;
6373 i += num;
6374 }
6375 if (numBuckets < 1) {
6376 return -1;
6377 }
6378 long averageTime = buckets[numBuckets-1];
6379 for (i=numBuckets-2; i>=0; i--) {
6380 averageTime = (averageTime + buckets[i]) / 2;
6381 }
6382 return averageTime;
6383 */
6384 }
6385
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006386 @Override
6387 public long computeBatteryTimeRemaining(long curTime) {
6388 if (!mOnBattery) {
6389 return -1;
6390 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07006391 /* Simple implementation just looks at the average discharge per level across the
6392 entire sample period.
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006393 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2;
6394 if (discharge < 2) {
6395 return -1;
6396 }
6397 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED);
6398 if (duration < 1000*1000) {
6399 return -1;
6400 }
6401 long usPerLevel = duration/discharge;
6402 return usPerLevel * mCurrentBatteryLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -07006403 */
6404 if (mNumDischargeStepDurations < 1) {
6405 return -1;
6406 }
6407 long msPerLevel = computeTimePerLevel(mDischargeStepDurations, mNumDischargeStepDurations);
6408 if (msPerLevel <= 0) {
6409 return -1;
6410 }
6411 return (msPerLevel * mCurrentBatteryLevel) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006412 }
6413
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07006414 public int getNumDischargeStepDurations() {
6415 return mNumDischargeStepDurations;
6416 }
6417
6418 public long[] getDischargeStepDurationsArray() {
6419 return mDischargeStepDurations;
6420 }
6421
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006422 @Override
6423 public long computeChargeTimeRemaining(long curTime) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07006424 if (mOnBattery) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006425 // Not yet working.
6426 return -1;
6427 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07006428 /* Broken
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006429 int curLevel = mCurrentBatteryLevel;
6430 int plugLevel = mDischargePlugLevel;
6431 if (plugLevel < 0 || curLevel < (plugLevel+1)) {
6432 return -1;
6433 }
6434 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED);
6435 if (duration < 1000*1000) {
6436 return -1;
6437 }
6438 long usPerLevel = duration/(curLevel-plugLevel);
6439 return usPerLevel * (100-curLevel);
Dianne Hackborn260c5022014-04-29 11:23:16 -07006440 */
6441 if (mNumChargeStepDurations < 1) {
6442 return -1;
6443 }
6444 long msPerLevel = computeTimePerLevel(mChargeStepDurations, mNumChargeStepDurations);
6445 if (msPerLevel <= 0) {
6446 return -1;
6447 }
6448 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006449 }
6450
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07006451 public int getNumChargeStepDurations() {
6452 return mNumChargeStepDurations;
6453 }
6454
6455 public long[] getChargeStepDurationsArray() {
6456 return mChargeStepDurations;
6457 }
6458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006459 long getBatteryUptimeLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006460 return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006461 }
6462
6463 @Override
6464 public long getBatteryUptime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006465 return mOnBatteryTimeBase.getUptime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006466 }
6467
6468 @Override
6469 public long getBatteryRealtime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006470 return mOnBatteryTimeBase.getRealtime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006471 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07006472
The Android Open Source Project10592532009-03-18 17:39:46 -07006473 @Override
Evan Millar633a1742009-04-02 16:36:33 -07006474 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07006475 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07006476 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07006477 }
6478 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006479
Evan Millar633a1742009-04-02 16:36:33 -07006480 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006481 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07006482 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006483
The Android Open Source Project10592532009-03-18 17:39:46 -07006484 @Override
Evan Millar633a1742009-04-02 16:36:33 -07006485 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07006486 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07006487 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07006488 }
6489 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006490
Evan Millar633a1742009-04-02 16:36:33 -07006491 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08006492 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07006493 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006494
Amith Yamasanie43530a2009-08-21 13:11:37 -07006495 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006496 public int getLowDischargeAmountSinceCharge() {
6497 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08006498 int val = mLowDischargeAmountSinceCharge;
6499 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
6500 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
6501 }
6502 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006503 }
6504 }
6505
6506 @Override
6507 public int getHighDischargeAmountSinceCharge() {
6508 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08006509 int val = mHighDischargeAmountSinceCharge;
6510 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
6511 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
6512 }
6513 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006514 }
6515 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07006516
6517 @Override
6518 public int getDischargeAmount(int which) {
6519 int dischargeAmount = which == STATS_SINCE_CHARGED
6520 ? getHighDischargeAmountSinceCharge()
6521 : (getDischargeStartLevel() - getDischargeCurrentLevel());
6522 if (dischargeAmount < 0) {
6523 dischargeAmount = 0;
6524 }
6525 return dischargeAmount;
6526 }
6527
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006528 public int getDischargeAmountScreenOn() {
6529 synchronized(this) {
6530 int val = mDischargeAmountScreenOn;
Jeff Browne95c3cd2014-05-02 16:59:26 -07006531 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006532 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
6533 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
6534 }
6535 return val;
6536 }
6537 }
6538
6539 public int getDischargeAmountScreenOnSinceCharge() {
6540 synchronized(this) {
6541 int val = mDischargeAmountScreenOnSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07006542 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006543 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
6544 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
6545 }
6546 return val;
6547 }
6548 }
6549
6550 public int getDischargeAmountScreenOff() {
6551 synchronized(this) {
6552 int val = mDischargeAmountScreenOff;
Jeff Browne95c3cd2014-05-02 16:59:26 -07006553 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006554 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
6555 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
6556 }
6557 return val;
6558 }
6559 }
6560
6561 public int getDischargeAmountScreenOffSinceCharge() {
6562 synchronized(this) {
6563 int val = mDischargeAmountScreenOffSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07006564 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006565 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
6566 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
6567 }
6568 return val;
6569 }
6570 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006571
6572 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07006573 public int getCpuSpeedSteps() {
6574 return sNumSpeedSteps;
6575 }
6576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006577 /**
6578 * Retrieve the statistics object for a particular uid, creating if needed.
6579 */
6580 public Uid getUidStatsLocked(int uid) {
6581 Uid u = mUidStats.get(uid);
6582 if (u == null) {
6583 u = new Uid(uid);
6584 mUidStats.put(uid, u);
6585 }
6586 return u;
6587 }
6588
6589 /**
6590 * Remove the statistics object for a particular uid.
6591 */
6592 public void removeUidStatsLocked(int uid) {
6593 mUidStats.remove(uid);
6594 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07006595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006596 /**
6597 * Retrieve the statistics object for a particular process, creating
6598 * if needed.
6599 */
6600 public Uid.Proc getProcessStatsLocked(int uid, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006601 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006602 Uid u = getUidStatsLocked(uid);
6603 return u.getProcessStatsLocked(name);
6604 }
6605
6606 /**
6607 * Retrieve the statistics object for a particular process, creating
6608 * if needed.
6609 */
6610 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006611 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006612 Uid u = getUidStatsLocked(uid);
6613 return u.getPackageStatsLocked(pkg);
6614 }
6615
6616 /**
6617 * Retrieve the statistics object for a particular service, creating
6618 * if needed.
6619 */
6620 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006621 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006622 Uid u = getUidStatsLocked(uid);
6623 return u.getServiceStatsLocked(pkg, name);
6624 }
6625
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006626 /**
6627 * Massage data to distribute any reasonable work down to more specific
6628 * owners. Must only be called on a dead BatteryStats object!
6629 */
6630 public void distributeWorkLocked(int which) {
6631 // Aggregate all CPU time associated with WIFI.
6632 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
6633 if (wifiUid != null) {
6634 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
6635 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
6636 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
6637 for (int i=0; i<mUidStats.size(); i++) {
6638 Uid uid = mUidStats.valueAt(i);
6639 if (uid.mUid != Process.WIFI_UID) {
6640 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
6641 if (uidRunningTime > 0) {
6642 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
6643 long time = proc.getUserTime(which);
6644 time = (time*uidRunningTime)/totalRunningTime;
6645 uidProc.mUserTime += time;
6646 proc.mUserTime -= time;
6647 time = proc.getSystemTime(which);
6648 time = (time*uidRunningTime)/totalRunningTime;
6649 uidProc.mSystemTime += time;
6650 proc.mSystemTime -= time;
6651 time = proc.getForegroundTime(which);
6652 time = (time*uidRunningTime)/totalRunningTime;
6653 uidProc.mForegroundTime += time;
6654 proc.mForegroundTime -= time;
6655 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
6656 SamplingCounter sc = proc.mSpeedBins[sb];
6657 if (sc != null) {
6658 time = sc.getCountLocked(which);
6659 time = (time*uidRunningTime)/totalRunningTime;
6660 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
6661 if (uidSc == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006662 uidSc = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006663 uidProc.mSpeedBins[sb] = uidSc;
6664 }
6665 uidSc.mCount.addAndGet((int)time);
6666 sc.mCount.addAndGet((int)-time);
6667 }
6668 }
6669 totalRunningTime -= uidRunningTime;
6670 }
6671 }
6672 }
6673 }
6674 }
6675 }
6676
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006677 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006678 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006679 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006680 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006681
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006682 Parcel mPendingWrite = null;
6683 final ReentrantLock mWriteLock = new ReentrantLock();
6684
6685 public void writeAsyncLocked() {
6686 writeLocked(false);
6687 }
6688
6689 public void writeSyncLocked() {
6690 writeLocked(true);
6691 }
6692
6693 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006694 if (mFile == null) {
6695 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006696 return;
6697 }
6698
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006699 if (mShuttingDown) {
6700 return;
6701 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006702
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006703 Parcel out = Parcel.obtain();
6704 writeSummaryToParcel(out);
6705 mLastWriteTime = SystemClock.elapsedRealtime();
6706
6707 if (mPendingWrite != null) {
6708 mPendingWrite.recycle();
6709 }
6710 mPendingWrite = out;
6711
6712 if (sync) {
6713 commitPendingDataToDisk();
6714 } else {
6715 Thread thr = new Thread("BatteryStats-Write") {
6716 @Override
6717 public void run() {
6718 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
6719 commitPendingDataToDisk();
6720 }
6721 };
6722 thr.start();
6723 }
6724 }
6725
6726 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07006727 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006728 synchronized (this) {
6729 next = mPendingWrite;
6730 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07006731 if (next == null) {
6732 return;
6733 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006734
6735 mWriteLock.lock();
6736 }
6737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006738 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006739 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006740 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006741 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006742 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006743 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006744 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006745 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006746 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006747 mFile.rollback();
6748 } finally {
6749 next.recycle();
6750 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07006751 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006752 }
6753
6754 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
6755 int pos = 0;
6756 int avail = stream.available();
6757 byte[] data = new byte[avail];
6758 while (true) {
6759 int amt = stream.read(data, pos, data.length-pos);
6760 //Log.i("foo", "Read " + amt + " bytes at " + pos
6761 // + " of avail " + data.length);
6762 if (amt <= 0) {
6763 //Log.i("foo", "**** FINISHED READING: pos=" + pos
6764 // + " len=" + data.length);
6765 return data;
6766 }
6767 pos += amt;
6768 avail = stream.available();
6769 if (avail > data.length-pos) {
6770 byte[] newData = new byte[pos+avail];
6771 System.arraycopy(data, 0, newData, 0, pos);
6772 data = newData;
6773 }
6774 }
6775 }
6776
6777 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006778 if (mFile == null) {
6779 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006780 return;
6781 }
6782
6783 mUidStats.clear();
6784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006786 File file = mFile.chooseForRead();
6787 if (!file.exists()) {
6788 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006789 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006790 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006791
6792 byte[] raw = readFully(stream);
6793 Parcel in = Parcel.obtain();
6794 in.unmarshall(raw, 0, raw.length);
6795 in.setDataPosition(0);
6796 stream.close();
6797
6798 readSummaryFromParcel(in);
Dianne Hackborn00e25212014-02-19 10:49:24 -08006799 } catch(Exception e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006800 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006801 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006802
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006803 if (mHistoryBuffer.dataPosition() > 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006804 mRecordingHistory = true;
Dianne Hackborn40c87252014-03-19 16:55:40 -07006805 final long elapsedRealtime = SystemClock.elapsedRealtime();
6806 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006807 if (USE_OLD_HISTORY) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006808 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006809 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006810 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
6811 startRecordingHistory(elapsedRealtime, uptime, false);
Dianne Hackborne8c88e62011-08-17 19:09:09 -07006812 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006813 }
6814
6815 public int describeContents() {
6816 return 0;
6817 }
6818
Dianne Hackbornae384452011-06-28 12:33:48 -07006819 void readHistory(Parcel in, boolean andOldHistory) {
6820 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006821
6822 mHistoryBuffer.setDataSize(0);
6823 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006824 mHistoryTagPool.clear();
6825 mNextHistoryTagIdx = 0;
6826 mNumHistoryTagChars = 0;
Dianne Hackborn099bc622014-01-22 13:39:16 -08006827
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006828 int numTags = in.readInt();
6829 for (int i=0; i<numTags; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08006830 int idx = in.readInt();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006831 String str = in.readString();
6832 int uid = in.readInt();
6833 HistoryTag tag = new HistoryTag();
6834 tag.string = str;
6835 tag.uid = uid;
6836 tag.poolIdx = idx;
6837 mHistoryTagPool.put(tag, idx);
6838 if (idx >= mNextHistoryTagIdx) {
6839 mNextHistoryTagIdx = idx+1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08006840 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006841 mNumHistoryTagChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08006842 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006843
6844 int bufSize = in.readInt();
6845 int curPos = in.dataPosition();
6846 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
6847 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
6848 } else if ((bufSize&~3) != bufSize) {
6849 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
6850 } else {
6851 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
6852 + " bytes at " + curPos);
6853 mHistoryBuffer.appendFrom(in, curPos, bufSize);
6854 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006855 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006856
Dianne Hackbornae384452011-06-28 12:33:48 -07006857 if (andOldHistory) {
6858 readOldHistory(in);
6859 }
6860
6861 if (DEBUG_HISTORY) {
6862 StringBuilder sb = new StringBuilder(128);
6863 sb.append("****************** OLD mHistoryBaseTime: ");
6864 TimeUtils.formatDuration(mHistoryBaseTime, sb);
6865 Slog.i(TAG, sb.toString());
6866 }
6867 mHistoryBaseTime = historyBaseTime;
6868 if (DEBUG_HISTORY) {
6869 StringBuilder sb = new StringBuilder(128);
6870 sb.append("****************** NEW mHistoryBaseTime: ");
6871 TimeUtils.formatDuration(mHistoryBaseTime, sb);
6872 Slog.i(TAG, sb.toString());
6873 }
6874
6875 // We are just arbitrarily going to insert 1 minute from the sample of
6876 // the last run until samples in this run.
6877 if (mHistoryBaseTime > 0) {
6878 long oldnow = SystemClock.elapsedRealtime();
6879 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000;
6880 if (DEBUG_HISTORY) {
6881 StringBuilder sb = new StringBuilder(128);
6882 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
6883 TimeUtils.formatDuration(mHistoryBaseTime, sb);
6884 Slog.i(TAG, sb.toString());
6885 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07006886 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006887 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006888
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006889 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07006890 if (!USE_OLD_HISTORY) {
6891 return;
6892 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006893 mHistory = mHistoryEnd = mHistoryCache = null;
6894 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07006895 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006896 HistoryItem rec = new HistoryItem(time, in);
6897 addHistoryRecordLocked(rec);
6898 }
6899 }
6900
Dianne Hackbornae384452011-06-28 12:33:48 -07006901 void writeHistory(Parcel out, boolean andOldHistory) {
6902 if (DEBUG_HISTORY) {
6903 StringBuilder sb = new StringBuilder(128);
6904 sb.append("****************** WRITING mHistoryBaseTime: ");
6905 TimeUtils.formatDuration(mHistoryBaseTime, sb);
Dianne Hackborn40c87252014-03-19 16:55:40 -07006906 sb.append(" mLastHistoryElapsedRealtime: ");
6907 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
Dianne Hackbornae384452011-06-28 12:33:48 -07006908 Slog.i(TAG, sb.toString());
6909 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07006910 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006911 out.writeInt(mHistoryTagPool.size());
6912 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
6913 HistoryTag tag = ent.getKey();
Dianne Hackborn099bc622014-01-22 13:39:16 -08006914 out.writeInt(ent.getValue());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006915 out.writeString(tag.string);
6916 out.writeInt(tag.uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08006917 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006918 out.writeInt(mHistoryBuffer.dataSize());
6919 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
6920 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
6921 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07006922
6923 if (andOldHistory) {
6924 writeOldHistory(out);
6925 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006926 }
6927
6928 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07006929 if (!USE_OLD_HISTORY) {
6930 return;
6931 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006932 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006933 while (rec != null) {
6934 if (rec.time >= 0) rec.writeToParcel(out, 0);
6935 rec = rec.next;
6936 }
6937 out.writeLong(-1);
6938 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006940 private void readSummaryFromParcel(Parcel in) {
6941 final int version = in.readInt();
6942 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006943 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006944 + ", expected " + VERSION + "; erasing old stats");
6945 return;
6946 }
6947
Dianne Hackbornae384452011-06-28 12:33:48 -07006948 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006950 mStartCount = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006951 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 mRealtime = in.readLong();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08006953 mStartClockTime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006954 mOnBatteryTimeBase.readSummaryFromParcel(in);
6955 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006956 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006957 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07006958 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006959 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006960 mLowDischargeAmountSinceCharge = in.readInt();
6961 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006962 mDischargeAmountScreenOnSinceCharge = in.readInt();
6963 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackborn260c5022014-04-29 11:23:16 -07006964 mNumDischargeStepDurations = in.readInt();
6965 in.readLongArray(mDischargeStepDurations);
6966 mNumChargeStepDurations = in.readInt();
6967 in.readLongArray(mChargeStepDurations);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006969 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006970
Jeff Browne95c3cd2014-05-02 16:59:26 -07006971 mScreenState = Display.STATE_UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006972 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006973 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
6974 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
6975 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07006976 mInteractive = false;
6977 mInteractiveTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006978 mPhoneOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006979 mLowPowerModeEnabledTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006980 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08006981 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07006982 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
6983 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07006984 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006985 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
6986 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
6987 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006988 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006989 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
6990 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006991 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006992 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08006993 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006994 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006995 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006996 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
6997 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07006998 mWifiOn = false;
6999 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007000 mGlobalWifiRunning = false;
7001 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007002 for (int i=0; i<NUM_WIFI_STATES; i++) {
7003 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
7004 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007005 mBluetoothOn = false;
7006 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007007 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
7008 mBluetoothStateTimer[i].readSummaryFromParcelLocked(in);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007009 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010
Evan Millarc64edde2009-04-18 12:26:32 -07007011 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007012 if (NKW > 10000) {
7013 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
7014 return;
7015 }
Evan Millarc64edde2009-04-18 12:26:32 -07007016 for (int ikw = 0; ikw < NKW; ikw++) {
7017 if (in.readInt() != 0) {
7018 String kwltName = in.readString();
7019 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
7020 }
7021 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07007022
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007023 int NWR = in.readInt();
7024 if (NWR > 10000) {
7025 Slog.w(TAG, "File corrupt: too many wakeup reasons " + NWR);
7026 return;
7027 }
7028 for (int iwr = 0; iwr < NWR; iwr++) {
7029 if (in.readInt() != 0) {
7030 String reasonName = in.readString();
7031 getWakeupReasonCounterLocked(reasonName).readSummaryFromParcelLocked(in);
7032 }
7033 }
7034
Amith Yamasanie43530a2009-08-21 13:11:37 -07007035 sNumSpeedSteps = in.readInt();
Dianne Hackborn00e25212014-02-19 10:49:24 -08007036 if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) {
7037 throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps);
7038 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07007039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007040 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007041 if (NU > 10000) {
7042 Slog.w(TAG, "File corrupt: too many uids " + NU);
7043 return;
7044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007045 for (int iu = 0; iu < NU; iu++) {
7046 int uid = in.readInt();
7047 Uid u = new Uid(uid);
7048 mUidStats.put(uid, u);
7049
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007050 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007051 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007052 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007053 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007054 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007055 if (in.readInt() != 0) {
7056 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
7057 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07007058 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007059 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07007060 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007061 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07007062 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
7063 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7064 if (in.readInt() != 0) {
7065 u.makeWifiBatchedScanBin(i, null);
7066 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
7067 }
7068 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07007069 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007070 if (in.readInt() != 0) {
7071 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
7072 }
7073 u.mAudioTurnedOn = false;
7074 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007075 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007076 }
7077 u.mVideoTurnedOn = false;
7078 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007079 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
7080 }
7081 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007082 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
7083 }
7084 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007085 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007086 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07007087
Dianne Hackborn617f8772009-03-31 15:04:46 -07007088 if (in.readInt() != 0) {
7089 if (u.mUserActivityCounters == null) {
7090 u.initUserActivityLocked();
7091 }
7092 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
7093 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
7094 }
7095 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007096
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007097 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007098 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007099 u.initNetworkActivityLocked();
7100 }
7101 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007102 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
7103 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007104 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007105 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
7106 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007107 }
7108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007109 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007110 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007111 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
7112 return;
7113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007114 for (int iw = 0; iw < NW; iw++) {
7115 String wlName = in.readString();
7116 if (in.readInt() != 0) {
7117 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
7118 }
7119 if (in.readInt() != 0) {
7120 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
7121 }
7122 if (in.readInt() != 0) {
7123 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
7124 }
7125 }
7126
7127 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007128 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007129 Slog.w(TAG, "File corrupt: too many sensors " + NP);
7130 return;
7131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 for (int is = 0; is < NP; is++) {
7133 int seNumber = in.readInt();
7134 if (in.readInt() != 0) {
7135 u.getSensorTimerLocked(seNumber, true)
7136 .readSummaryFromParcelLocked(in);
7137 }
7138 }
7139
7140 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007141 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007142 Slog.w(TAG, "File corrupt: too many processes " + NP);
7143 return;
7144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007145 for (int ip = 0; ip < NP; ip++) {
7146 String procName = in.readString();
7147 Uid.Proc p = u.getProcessStatsLocked(procName);
7148 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007149 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007150 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007151 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007152 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007153 if (NSB > 100) {
7154 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
7155 return;
7156 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007157 p.mSpeedBins = new SamplingCounter[NSB];
7158 for (int i=0; i<NSB; i++) {
7159 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007160 p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007161 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
7162 }
7163 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007164 if (!p.readExcessivePowerFromParcelLocked(in)) {
7165 return;
7166 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007167 }
7168
7169 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007170 if (NP > 10000) {
7171 Slog.w(TAG, "File corrupt: too many packages " + NP);
7172 return;
7173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007174 for (int ip = 0; ip < NP; ip++) {
7175 String pkgName = in.readString();
7176 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
7177 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007178 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007179 if (NS > 1000) {
7180 Slog.w(TAG, "File corrupt: too many services " + NS);
7181 return;
7182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007183 for (int is = 0; is < NS; is++) {
7184 String servName = in.readString();
7185 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
7186 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007187 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007189 }
7190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007191 }
7192 }
7193
7194 /**
7195 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
7196 * disk. This format does not allow a lossless round-trip.
7197 *
7198 * @param out the Parcel to be written to.
7199 */
7200 public void writeSummaryToParcel(Parcel out) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007201 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007203 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
7204 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007205
7206 out.writeInt(VERSION);
7207
Dianne Hackbornae384452011-06-28 12:33:48 -07007208 writeHistory(out, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007210 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007211 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007212 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007213 out.writeLong(mStartClockTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007214 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
7215 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007216 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007217 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07007218 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007219 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08007220 out.writeInt(getLowDischargeAmountSinceCharge());
7221 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007222 out.writeInt(getDischargeAmountScreenOnSinceCharge());
7223 out.writeInt(getDischargeAmountScreenOffSinceCharge());
Dianne Hackborn260c5022014-04-29 11:23:16 -07007224 out.writeInt(mNumDischargeStepDurations);
7225 out.writeLongArray(mDischargeStepDurations);
7226 out.writeInt(mNumChargeStepDurations);
7227 out.writeLongArray(mChargeStepDurations);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007228
7229 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007230 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007231 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007232 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007233 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007234 mLowPowerModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007235 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Wink Saville52840902011-02-18 12:40:47 -08007236 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007237 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07007238 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007239 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07007240 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007241 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07007242 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007243 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007244 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
7245 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007246 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007247 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
7248 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007249 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007250 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
7251 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007252 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
7253 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007254 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007255 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007256 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007257 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007258 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007259 mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007261
Evan Millarc64edde2009-04-18 12:26:32 -07007262 out.writeInt(mKernelWakelockStats.size());
7263 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
7264 Timer kwlt = ent.getValue();
7265 if (kwlt != null) {
7266 out.writeInt(1);
7267 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007268 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
7269 } else {
7270 out.writeInt(0);
7271 }
7272 }
7273
7274 out.writeInt(mWakeupReasonStats.size());
7275 for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) {
7276 LongSamplingCounter counter = ent.getValue();
7277 if (counter != null) {
7278 out.writeInt(1);
7279 out.writeString(ent.getKey());
7280 counter.writeSummaryFromParcelLocked(out);
Evan Millarc64edde2009-04-18 12:26:32 -07007281 } else {
7282 out.writeInt(0);
7283 }
7284 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007285
Amith Yamasanie43530a2009-08-21 13:11:37 -07007286 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007287 final int NU = mUidStats.size();
7288 out.writeInt(NU);
7289 for (int iu = 0; iu < NU; iu++) {
7290 out.writeInt(mUidStats.keyAt(iu));
7291 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007292
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007293 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007294 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007295 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007296 } else {
7297 out.writeInt(0);
7298 }
7299 if (u.mFullWifiLockTimer != null) {
7300 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007301 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007302 } else {
7303 out.writeInt(0);
7304 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07007305 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007306 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007307 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007308 } else {
7309 out.writeInt(0);
7310 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07007311 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7312 if (u.mWifiBatchedScanTimer[i] != null) {
7313 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007314 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Robert Greenwalta029ea12013-09-25 16:38:12 -07007315 } else {
7316 out.writeInt(0);
7317 }
7318 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007319 if (u.mWifiMulticastTimer != null) {
7320 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007321 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007322 } else {
7323 out.writeInt(0);
7324 }
7325 if (u.mAudioTurnedOnTimer != null) {
7326 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007327 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007328 } else {
7329 out.writeInt(0);
7330 }
7331 if (u.mVideoTurnedOnTimer != null) {
7332 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007333 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007334 } else {
7335 out.writeInt(0);
7336 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007337 if (u.mForegroundActivityTimer != null) {
7338 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007339 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007340 } else {
7341 out.writeInt(0);
7342 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007343 if (u.mVibratorOnTimer != null) {
7344 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007345 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007346 } else {
7347 out.writeInt(0);
7348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007349
Dianne Hackborn617f8772009-03-31 15:04:46 -07007350 if (u.mUserActivityCounters == null) {
7351 out.writeInt(0);
7352 } else {
7353 out.writeInt(1);
7354 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
7355 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
7356 }
7357 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007358
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007359 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007360 out.writeInt(0);
7361 } else {
7362 out.writeInt(1);
7363 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007364 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
7365 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007366 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007367 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
7368 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007369 }
7370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007371 int NW = u.mWakelockStats.size();
7372 out.writeInt(NW);
7373 if (NW > 0) {
7374 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
7375 : u.mWakelockStats.entrySet()) {
7376 out.writeString(ent.getKey());
7377 Uid.Wakelock wl = ent.getValue();
7378 if (wl.mTimerFull != null) {
7379 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007380 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007381 } else {
7382 out.writeInt(0);
7383 }
7384 if (wl.mTimerPartial != null) {
7385 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007386 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007387 } else {
7388 out.writeInt(0);
7389 }
7390 if (wl.mTimerWindow != null) {
7391 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007392 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007393 } else {
7394 out.writeInt(0);
7395 }
7396 }
7397 }
7398
7399 int NSE = u.mSensorStats.size();
7400 out.writeInt(NSE);
7401 if (NSE > 0) {
7402 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
7403 : u.mSensorStats.entrySet()) {
7404 out.writeInt(ent.getKey());
7405 Uid.Sensor se = ent.getValue();
7406 if (se.mTimer != null) {
7407 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007408 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007409 } else {
7410 out.writeInt(0);
7411 }
7412 }
7413 }
7414
7415 int NP = u.mProcessStats.size();
7416 out.writeInt(NP);
7417 if (NP > 0) {
7418 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
7419 : u.mProcessStats.entrySet()) {
7420 out.writeString(ent.getKey());
7421 Uid.Proc ps = ent.getValue();
7422 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007423 out.writeLong(ps.mSystemTime);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007424 out.writeLong(ps.mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007425 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007426 final int N = ps.mSpeedBins.length;
7427 out.writeInt(N);
7428 for (int i=0; i<N; i++) {
7429 if (ps.mSpeedBins[i] != null) {
7430 out.writeInt(1);
7431 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
7432 } else {
7433 out.writeInt(0);
7434 }
7435 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007436 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007437 }
7438 }
7439
7440 NP = u.mPackageStats.size();
7441 out.writeInt(NP);
7442 if (NP > 0) {
7443 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
7444 : u.mPackageStats.entrySet()) {
7445 out.writeString(ent.getKey());
7446 Uid.Pkg ps = ent.getValue();
7447 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007448 final int NS = ps.mServiceStats.size();
7449 out.writeInt(NS);
7450 if (NS > 0) {
7451 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
7452 : ps.mServiceStats.entrySet()) {
7453 out.writeString(sent.getKey());
7454 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007455 long time = ss.getStartTimeToNowLocked(
7456 mOnBatteryTimeBase.getUptime(NOW_SYS));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007457 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007458 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007459 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007460 }
7461 }
7462 }
7463 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007464 }
7465 }
7466
7467 public void readFromParcel(Parcel in) {
7468 readFromParcelLocked(in);
7469 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007471 void readFromParcelLocked(Parcel in) {
7472 int magic = in.readInt();
7473 if (magic != MAGIC) {
7474 throw new ParcelFormatException("Bad magic number");
7475 }
7476
Dianne Hackbornae384452011-06-28 12:33:48 -07007477 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007479 mStartCount = in.readInt();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007480 mStartClockTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007481 mUptime = in.readLong();
7482 mUptimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007483 mRealtime = in.readLong();
7484 mRealtimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007485 mOnBattery = in.readInt() != 0;
7486 mOnBatteryInternal = false; // we are no longer really running.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007487 mOnBatteryTimeBase.readFromParcel(in);
7488 mOnBatteryScreenOffTimeBase.readFromParcel(in);
7489
Jeff Browne95c3cd2014-05-02 16:59:26 -07007490 mScreenState = Display.STATE_UNKNOWN;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007491 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase, in);
7492 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
7493 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase,
7494 in);
7495 }
Dianne Hackborn29325132014-05-21 15:01:03 -07007496 mInteractive = false;
7497 mInteractiveTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007498 mPhoneOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007499 mLowPowerModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
7500 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007501 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
7502 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
7503 null, mOnBatteryTimeBase, in);
7504 }
7505 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase, in);
7506 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
7507 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
7508 null, mOnBatteryTimeBase, in);
7509 }
7510 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
7511 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
7512 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
7513 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007514 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007515 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in);
7516 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase,
7517 in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007518 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007519 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
7520 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
7521 mWifiOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007522 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007523 mGlobalWifiRunning = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007524 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007525 for (int i=0; i<NUM_WIFI_STATES; i++) {
7526 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
7527 null, mOnBatteryTimeBase, in);
7528 }
7529 mBluetoothOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007530 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007531 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
7532 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i,
7533 null, mOnBatteryTimeBase, in);
7534 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007535 mAudioOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007536 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
Jeff Browne95c3cd2014-05-02 16:59:26 -07007537 mVideoOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007538 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007539 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007540 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07007541 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007542 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007543 mLowDischargeAmountSinceCharge = in.readInt();
7544 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007545 mDischargeAmountScreenOn = in.readInt();
7546 mDischargeAmountScreenOnSinceCharge = in.readInt();
7547 mDischargeAmountScreenOff = in.readInt();
7548 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackborn260c5022014-04-29 11:23:16 -07007549 mNumDischargeStepDurations = in.readInt();
7550 in.readLongArray(mDischargeStepDurations);
7551 mNumChargeStepDurations = in.readInt();
7552 in.readLongArray(mChargeStepDurations);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007553 mLastWriteTime = in.readLong();
7554
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07007555 mBluetoothPingCount = in.readInt();
7556 mBluetoothPingStart = -1;
7557
Evan Millarc64edde2009-04-18 12:26:32 -07007558 mKernelWakelockStats.clear();
7559 int NKW = in.readInt();
7560 for (int ikw = 0; ikw < NKW; ikw++) {
7561 if (in.readInt() != 0) {
7562 String wakelockName = in.readString();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007563 SamplingTimer kwlt = new SamplingTimer(mOnBatteryTimeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07007564 mKernelWakelockStats.put(wakelockName, kwlt);
7565 }
7566 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007567
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007568 mWakeupReasonStats.clear();
7569 int NWR = in.readInt();
7570 for (int iwr = 0; iwr < NWR; iwr++) {
7571 if (in.readInt() != 0) {
7572 String reasonName = in.readString();
7573 LongSamplingCounter counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase,
7574 in);
7575 mWakeupReasonStats.put(reasonName, counter);
7576 }
7577 }
7578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007579 mPartialTimers.clear();
7580 mFullTimers.clear();
7581 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007582 mWifiRunningTimers.clear();
7583 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -07007584 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -07007585 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007586 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007587
Amith Yamasanie43530a2009-08-21 13:11:37 -07007588 sNumSpeedSteps = in.readInt();
7589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007590 int numUids = in.readInt();
7591 mUidStats.clear();
7592 for (int i = 0; i < numUids; i++) {
7593 int uid = in.readInt();
7594 Uid u = new Uid(uid);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007595 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007596 mUidStats.append(uid, u);
7597 }
7598 }
7599
7600 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007601 writeToParcelLocked(out, true, flags);
7602 }
7603
7604 public void writeToParcelWithoutUids(Parcel out, int flags) {
7605 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007606 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007607
7608 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007609 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007610 // Need to update with current kernel wake lock counts.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007611 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007613 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
7614 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007615 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
7616 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007618 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007619
Dianne Hackbornae384452011-06-28 12:33:48 -07007620 writeHistory(out, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007622 out.writeInt(mStartCount);
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007623 out.writeLong(mStartClockTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007624 out.writeLong(mUptime);
7625 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007626 out.writeLong(mRealtime);
7627 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007628 out.writeInt(mOnBattery ? 1 : 0);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007629 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
7630 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
7631
7632 mScreenOnTimer.writeToParcel(out, uSecRealtime);
7633 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
7634 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
7635 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007636 mInteractiveTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007637 mLowPowerModeEnabledTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007638 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
7639 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
7640 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
7641 }
7642 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
7643 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
7644 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
7645 }
7646 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
7647 mNetworkByteActivityCounters[i].writeToParcel(out);
7648 mNetworkPacketActivityCounters[i].writeToParcel(out);
7649 }
7650 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
7651 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007652 mMobileRadioActiveAdjustedTime.writeToParcel(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007653 mMobileRadioActiveUnknownTime.writeToParcel(out);
7654 mMobileRadioActiveUnknownCount.writeToParcel(out);
7655 mWifiOnTimer.writeToParcel(out, uSecRealtime);
7656 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
7657 for (int i=0; i<NUM_WIFI_STATES; i++) {
7658 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
7659 }
7660 mBluetoothOnTimer.writeToParcel(out, uSecRealtime);
7661 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
7662 mBluetoothStateTimer[i].writeToParcel(out, uSecRealtime);
7663 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007664 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007665 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07007666 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007667 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007668 out.writeInt(mLowDischargeAmountSinceCharge);
7669 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007670 out.writeInt(mDischargeAmountScreenOn);
7671 out.writeInt(mDischargeAmountScreenOnSinceCharge);
7672 out.writeInt(mDischargeAmountScreenOff);
7673 out.writeInt(mDischargeAmountScreenOffSinceCharge);
Dianne Hackborn260c5022014-04-29 11:23:16 -07007674 out.writeInt(mNumDischargeStepDurations);
7675 out.writeLongArray(mDischargeStepDurations);
7676 out.writeInt(mNumChargeStepDurations);
7677 out.writeLongArray(mChargeStepDurations);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007678 out.writeLong(mLastWriteTime);
7679
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07007680 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07007681
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007682 if (inclUids) {
7683 out.writeInt(mKernelWakelockStats.size());
7684 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
7685 SamplingTimer kwlt = ent.getValue();
7686 if (kwlt != null) {
7687 out.writeInt(1);
7688 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007689 kwlt.writeToParcel(out, uSecRealtime);
7690 } else {
7691 out.writeInt(0);
7692 }
7693 }
7694 out.writeInt(mWakeupReasonStats.size());
7695 for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) {
7696 LongSamplingCounter counter = ent.getValue();
7697 if (counter != null) {
7698 out.writeInt(1);
7699 out.writeString(ent.getKey());
7700 counter.writeToParcel(out);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007701 } else {
7702 out.writeInt(0);
7703 }
Evan Millarc64edde2009-04-18 12:26:32 -07007704 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007705 } else {
7706 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07007707 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07007708
7709 out.writeInt(sNumSpeedSteps);
7710
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007711 if (inclUids) {
7712 int size = mUidStats.size();
7713 out.writeInt(size);
7714 for (int i = 0; i < size; i++) {
7715 out.writeInt(mUidStats.keyAt(i));
7716 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007717
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007718 uid.writeToParcelLocked(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007719 }
7720 } else {
7721 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007722 }
7723 }
7724
7725 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
7726 new Parcelable.Creator<BatteryStatsImpl>() {
7727 public BatteryStatsImpl createFromParcel(Parcel in) {
7728 return new BatteryStatsImpl(in);
7729 }
7730
7731 public BatteryStatsImpl[] newArray(int size) {
7732 return new BatteryStatsImpl[size];
7733 }
7734 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007735
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007736 public void prepareForDumpLocked() {
7737 // Need to retrieve current kernel wake lock stats before printing.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007738 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007739 }
7740
Dianne Hackbornc51cf032014-03-02 19:08:15 -08007741 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007742 if (DEBUG) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007743 pw.println("mOnBatteryTimeBase:");
7744 mOnBatteryTimeBase.dump(pw, " ");
7745 pw.println("mOnBatteryScreenOffTimeBase:");
7746 mOnBatteryScreenOffTimeBase.dump(pw, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007747 Printer pr = new PrintWriterPrinter(pw);
7748 pr.println("*** Screen timer:");
7749 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07007750 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007751 pr.println("*** Screen brightness #" + i + ":");
7752 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07007753 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007754 pr.println("*** Interactive timer:");
7755 mInteractiveTimer.logState(pr, " ");
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007756 pr.println("*** Low power mode timer:");
7757 mLowPowerModeEnabledTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007758 pr.println("*** Phone timer:");
7759 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08007760 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007761 pr.println("*** Signal strength #" + i + ":");
7762 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07007763 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07007764 pr.println("*** Signal scanning :");
7765 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07007766 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007767 pr.println("*** Data connection type #" + i + ":");
7768 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07007769 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007770 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007771 pr.println("*** Mobile network active timer:");
7772 mMobileRadioActiveTimer.logState(pr, " ");
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007773 pr.println("*** Mobile network active adjusted timer:");
7774 mMobileRadioActiveAdjustedTime.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007775 pr.println("*** Wifi timer:");
7776 mWifiOnTimer.logState(pr, " ");
7777 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007778 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007779 for (int i=0; i<NUM_WIFI_STATES; i++) {
7780 pr.println("*** Wifi state #" + i + ":");
7781 mWifiStateTimer[i].logState(pr, " ");
7782 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007783 pr.println("*** Bluetooth timer:");
7784 mBluetoothOnTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007785 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007786 pr.println("*** Bluetooth active type #" + i + ":");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007787 mBluetoothStateTimer[i].logState(pr, " ");
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007789 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08007790 super.dumpLocked(context, pw, flags, reqUid, histStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007791 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007792}