blob: 240d520c066dc54298054fde5abd21e2bfc30dd8 [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 Hackbornfc064132014-06-02 12:42:12 -07002009 @Override
2010 public void commitCurrentHistoryBatchLocked() {
2011 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
2012 }
2013
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002014 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002015 if (!mHaveBatteryLevel || !mRecordingHistory) {
2016 return;
2017 }
2018
Dianne Hackborn40c87252014-03-19 16:55:40 -07002019 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002020 final int diffStates = mHistoryLastWritten.states^cur.states;
2021 final int diffStates2 = mHistoryLastWritten.states2^cur.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002022 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002023 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002024 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
2025 + Integer.toHexString(diffStates) + " lastDiff="
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002026 + Integer.toHexString(lastDiffStates) + " diff2="
2027 + Integer.toHexString(diffStates2) + " lastDiff2="
2028 + Integer.toHexString(lastDiffStates2));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002029 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002030 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002031 && (diffStates2&lastDiffStates2) == 0
2032 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
2033 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002034 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002035 || cur.eventCode == HistoryItem.EVENT_NONE)
2036 && mHistoryLastWritten.batteryLevel == cur.batteryLevel
2037 && mHistoryLastWritten.batteryStatus == cur.batteryStatus
2038 && mHistoryLastWritten.batteryHealth == cur.batteryHealth
2039 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
2040 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
2041 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002042 // We can merge this new change in with the last one. Merging is
Dianne Hackborn40c87252014-03-19 16:55:40 -07002043 // allowed as long as only the states have changed, and within those states
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002044 // as long as no bit has changed both between now and the last entry, as
2045 // well as the last entry and the one before it (so we capture any toggles).
2046 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002047 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
2048 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
2049 mHistoryBufferLastPos = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002050 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002051 // If the last written history had a wakelock tag, we need to retain it.
2052 // Note that the condition above made sure that we aren't in a case where
2053 // both it and the current history item have a wakelock tag.
2054 if (mHistoryLastWritten.wakelockTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002055 cur.wakelockTag = cur.localWakelockTag;
2056 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002057 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002058 // If the last written history had a wake reason tag, we need to retain it.
2059 // Note that the condition above made sure that we aren't in a case where
2060 // both it and the current history item have a wakelock tag.
2061 if (mHistoryLastWritten.wakeReasonTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002062 cur.wakeReasonTag = cur.localWakeReasonTag;
2063 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002064 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002065 // If the last written history had an event, we need to retain it.
2066 // Note that the condition above made sure that we aren't in a case where
2067 // both it and the current history item have an event.
2068 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002069 cur.eventCode = mHistoryLastWritten.eventCode;
2070 cur.eventTag = cur.localEventTag;
2071 cur.eventTag.setTo(mHistoryLastWritten.eventTag);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002072 }
Dianne Hackborn1fadab52011-04-14 17:57:33 -07002073 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002074 }
2075
2076 final int dataSize = mHistoryBuffer.dataSize();
2077 if (dataSize >= MAX_HISTORY_BUFFER) {
2078 if (!mHistoryOverflow) {
2079 mHistoryOverflow = true;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002080 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
2081 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002082 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002083 }
2084
2085 // Once we've reached the maximum number of items, we only
2086 // record changes to the battery level and the most interesting states.
2087 // Once we've reached the maximum maximum number of items, we only
2088 // record changes to the battery level.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002089 if (mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002090 (dataSize >= MAX_MAX_HISTORY_BUFFER
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002091 || ((mHistoryLastWritten.states^cur.states)
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002092 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
2093 return;
2094 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002095
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002096 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002097 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002098 }
2099
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002100 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002101 }
2102
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002103 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
2104 HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002105 if (mIteratingHistory) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002106 throw new IllegalStateException("Can't do this while iterating history!");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002107 }
2108 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
2109 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002110 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002111 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07002112 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002113 cur.wakelockTag = null;
2114 cur.wakeReasonTag = null;
2115 cur.eventCode = HistoryItem.EVENT_NONE;
2116 cur.eventTag = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002117 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
2118 + " now " + mHistoryBuffer.dataPosition()
2119 + " size is now " + mHistoryBuffer.dataSize());
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002120 }
2121
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002122 int mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002123 int mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002124
Dianne Hackborn40c87252014-03-19 16:55:40 -07002125 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002126 if (mTrackRunningHistoryElapsedRealtime != 0) {
2127 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
2128 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
2129 if (diffUptime < (diffElapsed-20)) {
2130 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
2131 mHistoryAddTmp.setTo(mHistoryLastWritten);
2132 mHistoryAddTmp.wakelockTag = null;
2133 mHistoryAddTmp.wakeReasonTag = null;
2134 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
2135 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
2136 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
2137 }
2138 }
2139 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
2140 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
2141 mTrackRunningHistoryUptime = uptimeMs;
2142 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
2143 }
2144
2145 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
2146 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002147
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002148 if (!USE_OLD_HISTORY) {
2149 return;
2150 }
2151
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002152 if (!mHaveBatteryLevel || !mRecordingHistory) {
2153 return;
2154 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002155
2156 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002157 // and no states have since the last recorded entry changed and
2158 // are now resetting back to their original value, then just collapse
2159 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002160 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002161 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002162 && ((mHistoryEnd.states^cur.states)&mChangedStates) == 0
2163 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002164 // If the current is the same as the one before, then we no
2165 // longer need the entry.
2166 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002167 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002168 && mHistoryLastEnd.sameNonEvent(cur)) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002169 mHistoryLastEnd.next = null;
2170 mHistoryEnd.next = mHistoryCache;
2171 mHistoryCache = mHistoryEnd;
2172 mHistoryEnd = mHistoryLastEnd;
2173 mHistoryLastEnd = null;
2174 } else {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002175 mChangedStates |= mHistoryEnd.states^cur.states;
2176 mChangedStates2 |= mHistoryEnd.states^cur.states2;
2177 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002178 }
2179 return;
2180 }
2181
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002182 mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002183 mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002184
2185 if (mNumHistoryItems == MAX_HISTORY_ITEMS
2186 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002187 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002188 }
2189
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002190 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
2191 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002192 // record changes to the battery level and the most interesting states.
2193 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002194 // record changes to the battery level.
2195 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002196 == cur.batteryLevel &&
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002197 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002198 || ((mHistoryEnd.states^cur.states)
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002199 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002200 return;
2201 }
2202 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002203
Dianne Hackborn40c87252014-03-19 16:55:40 -07002204 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002205 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002206
Dianne Hackborn40c87252014-03-19 16:55:40 -07002207 void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
2208 String name, int uid) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002209 mHistoryCur.eventCode = code;
2210 mHistoryCur.eventTag = mHistoryCur.localEventTag;
2211 mHistoryCur.eventTag.string = name;
2212 mHistoryCur.eventTag.uid = uid;
Dianne Hackborn4590e522014-03-24 13:36:46 -07002213 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002214 }
2215
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002216 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002217 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002218 if (rec != null) {
2219 mHistoryCache = rec.next;
2220 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002221 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002222 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002223 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002224
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002225 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002226 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002227
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002228 void addHistoryRecordLocked(HistoryItem rec) {
2229 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002230 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002231 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002232 if (mHistoryEnd != null) {
2233 mHistoryEnd.next = rec;
2234 mHistoryEnd = rec;
2235 } else {
2236 mHistory = mHistoryEnd = rec;
2237 }
2238 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002239
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002240 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002241 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002242 if (USE_OLD_HISTORY) {
2243 if (mHistory != null) {
2244 mHistoryEnd.next = mHistoryCache;
2245 mHistoryCache = mHistory;
2246 mHistory = mHistoryLastEnd = mHistoryEnd = null;
2247 }
2248 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002249 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002250
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002251 mHistoryBaseTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002252 mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002253 mTrackRunningHistoryElapsedRealtime = 0;
2254 mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002255
2256 mHistoryBuffer.setDataSize(0);
2257 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002258 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002259 mHistoryLastLastWritten.clear();
2260 mHistoryLastWritten.clear();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002261 mHistoryTagPool.clear();
2262 mNextHistoryTagIdx = 0;
2263 mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002264 mHistoryBufferLastPos = -1;
2265 mHistoryOverflow = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002266 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002267
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002268 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
2269 long realtime) {
2270 if (mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime)) {
2271 if (unplugged) {
2272 // Track bt headset ping count
2273 mBluetoothPingStart = getCurrentBluetoothPingCount();
2274 mBluetoothPingCount = 0;
2275 } else {
2276 // Track bt headset ping count
2277 mBluetoothPingCount = getBluetoothPingCount();
2278 mBluetoothPingStart = -1;
2279 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002280 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002281
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002282 boolean unpluggedScreenOff = unplugged && screenOff;
2283 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
2284 updateKernelWakelocksLocked();
2285 requestWakelockCpuUpdate();
2286 if (!unpluggedScreenOff) {
2287 // We are switching to no longer tracking wake locks, but we want
2288 // the next CPU update we receive to take them in to account.
2289 mDistributeWakelockCpu = true;
2290 }
2291 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 }
2293 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002294
Dianne Hackborn099bc622014-01-22 13:39:16 -08002295 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
2296 mIsolatedUids.put(isolatedUid, appUid);
2297 }
2298
2299 public void removeIsolatedUidLocked(int isolatedUid, int appUid) {
2300 int curUid = mIsolatedUids.get(isolatedUid, -1);
2301 if (curUid == appUid) {
2302 mIsolatedUids.delete(isolatedUid);
2303 }
2304 }
2305
2306 public int mapUid(int uid) {
2307 int isolated = mIsolatedUids.get(uid, -1);
2308 return isolated > 0 ? isolated : uid;
2309 }
2310
2311 public void noteEventLocked(int code, String name, int uid) {
2312 uid = mapUid(uid);
Dianne Hackborn37de0982014-05-09 09:32:18 -07002313 if (!mActiveEvents.updateState(code, name, uid, 0)) {
2314 return;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002315 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07002316 final long elapsedRealtime = SystemClock.elapsedRealtime();
2317 final long uptime = SystemClock.uptimeMillis();
2318 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002319 }
2320
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002321 private void requestWakelockCpuUpdate() {
2322 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
2323 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
2324 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
2325 }
2326 }
2327
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002328 public void setRecordAllWakeLocksLocked(boolean enabled) {
2329 mRecordAllWakeLocks = enabled;
2330 if (!enabled) {
2331 // Clear out any existing state.
2332 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK);
2333 }
2334 }
2335
Dianne Hackborn9a755432014-05-15 17:05:22 -07002336 public void setNoAutoReset(boolean enabled) {
2337 mNoAutoReset = enabled;
2338 }
2339
2340 private String mInitialAcquireWakeName;
2341 private int mInitialAcquireWakeUid = -1;
2342
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002343 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002344 boolean unimportantForLogging, long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002345 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002346 if (type == WAKE_TYPE_PARTIAL) {
2347 // Only care about partial wake locks, since full wake locks
2348 // will be canceled when the user puts the screen to sleep.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002349 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002350 if (historyName == null) {
2351 historyName = name;
2352 }
Dianne Hackborn536456f2014-05-23 16:51:05 -07002353 if (mRecordAllWakeLocks) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002354 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
2355 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002356 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002357 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002358 }
2359 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002360 if (mWakeLockNesting == 0) {
2361 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
2362 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
2363 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002364 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002365 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002366 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002367 mWakeLockImportant = !unimportantForLogging;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002368 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002369 } else if (!mWakeLockImportant && !unimportantForLogging
2370 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002371 if (mHistoryLastWritten.wakelockTag != null) {
2372 // We'll try to update the last tag.
2373 mHistoryLastWritten.wakelockTag = null;
2374 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002375 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002376 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002377 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002378 }
2379 mWakeLockImportant = true;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002380 }
2381 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002382 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002383 if (uid >= 0) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002384 //if (uid == 0) {
2385 // Slog.wtf(TAG, "Acquiring wake lock from root: " + name);
2386 //}
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002387 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002388 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002389 }
2390 }
2391
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002392 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type,
2393 long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002394 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002395 if (type == WAKE_TYPE_PARTIAL) {
2396 mWakeLockNesting--;
Dianne Hackborn536456f2014-05-23 16:51:05 -07002397 if (mRecordAllWakeLocks) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002398 if (historyName == null) {
2399 historyName = name;
2400 }
2401 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
2402 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002403 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002404 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002405 }
2406 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002407 if (mWakeLockNesting == 0) {
2408 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
2409 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
2410 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn37de0982014-05-09 09:32:18 -07002411 mInitialAcquireWakeName = null;
2412 mInitialAcquireWakeUid = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002413 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002414 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002415 }
2416 if (uid >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002417 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002418 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002419 }
2420 }
2421
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002422 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
2423 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002424 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002425 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002426 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002427 for (int i=0; i<N; i++) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002428 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002429 elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002430 }
2431 }
2432
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002433 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
2434 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002435 String newHistoryName, int newType, boolean newUnimportantForLogging) {
2436 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002437 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002438 // For correct semantics, we start the need worksources first, so that we won't
2439 // make inappropriate history items as if all wake locks went away and new ones
2440 // appeared. This is okay because tracking of wake locks allows nesting.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002441 final int NN = newWs.size();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002442 for (int i=0; i<NN; i++) {
2443 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002444 newUnimportantForLogging, elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002445 }
2446 final int NO = ws.size();
2447 for (int i=0; i<NO; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002448 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002449 }
2450 }
2451
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002452 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
2453 String historyName, int type) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002454 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002455 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002456 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002457 for (int i=0; i<N; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002458 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002459 }
2460 }
2461
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002462 void aggregateLastWakeupUptimeLocked(long uptimeMs) {
2463 if (mLastWakeupReason != null) {
2464 long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
2465 LongSamplingCounter timer = getWakeupReasonCounterLocked(mLastWakeupReason);
2466 timer.addCountLocked(deltaUptime);
2467 mLastWakeupReason = null;
2468 }
2469 }
2470
2471 public void noteWakeupReasonLocked(String reason) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002472 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002473 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002474 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason reason \"" + reason +"\": "
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002475 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002476 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002477 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
2478 mHistoryCur.wakeReasonTag.string = reason;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002479 mHistoryCur.wakeReasonTag.uid = 0;
2480 mLastWakeupReason = reason;
2481 mLastWakeupUptimeMs = uptime;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002482 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002483 }
2484
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002485 public int startAddingCpuLocked() {
2486 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2487
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002488 final int N = mPartialTimers.size();
2489 if (N == 0) {
2490 mLastPartialTimers.clear();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002491 mDistributeWakelockCpu = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002492 return 0;
2493 }
2494
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002495 if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) {
2496 return 0;
2497 }
2498
2499 mDistributeWakelockCpu = false;
2500
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002501 // How many timers should consume CPU? Only want to include ones
2502 // that have already been in the list.
2503 for (int i=0; i<N; i++) {
2504 StopwatchTimer st = mPartialTimers.get(i);
2505 if (st.mInList) {
2506 Uid uid = st.mUid;
2507 // We don't include the system UID, because it so often
2508 // holds wake locks at one request or another of an app.
2509 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2510 return 50;
2511 }
2512 }
2513 }
2514
2515 return 0;
2516 }
2517
2518 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
2519 final int N = mPartialTimers.size();
2520 if (perc != 0) {
2521 int num = 0;
2522 for (int i=0; i<N; i++) {
2523 StopwatchTimer st = mPartialTimers.get(i);
2524 if (st.mInList) {
2525 Uid uid = st.mUid;
2526 // We don't include the system UID, because it so often
2527 // holds wake locks at one request or another of an app.
2528 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2529 num++;
2530 }
2531 }
2532 }
2533 if (num != 0) {
2534 for (int i=0; i<N; i++) {
2535 StopwatchTimer st = mPartialTimers.get(i);
2536 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002537 Uid uid = st.mUid;
2538 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07002539 int myUTime = utime/num;
2540 int mySTime = stime/num;
2541 utime -= myUTime;
2542 stime -= mySTime;
2543 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002544 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
2545 proc.addCpuTimeLocked(myUTime, mySTime);
2546 proc.addSpeedStepTimes(cpuSpeedTimes);
2547 }
2548 }
2549 }
2550 }
2551
2552 // Just in case, collect any lost CPU time.
2553 if (utime != 0 || stime != 0) {
2554 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
2555 if (uid != null) {
2556 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
2557 proc.addCpuTimeLocked(utime, stime);
2558 proc.addSpeedStepTimes(cpuSpeedTimes);
2559 }
2560 }
2561 }
2562
2563 final int NL = mLastPartialTimers.size();
2564 boolean diff = N != NL;
2565 for (int i=0; i<NL && !diff; i++) {
2566 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
2567 }
2568 if (!diff) {
2569 for (int i=0; i<NL; i++) {
2570 mPartialTimers.get(i).mInList = true;
2571 }
2572 return;
2573 }
2574
2575 for (int i=0; i<NL; i++) {
2576 mLastPartialTimers.get(i).mInList = false;
2577 }
2578 mLastPartialTimers.clear();
2579 for (int i=0; i<N; i++) {
2580 StopwatchTimer st = mPartialTimers.get(i);
2581 st.mInList = true;
2582 mLastPartialTimers.add(st);
2583 }
2584 }
2585
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002586 public void noteProcessDiedLocked(int uid, int pid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002587 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002588 Uid u = mUidStats.get(uid);
2589 if (u != null) {
2590 u.mPids.remove(pid);
2591 }
2592 }
2593
2594 public long getProcessWakeTime(int uid, int pid, long realtime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002595 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002596 Uid u = mUidStats.get(uid);
2597 if (u != null) {
2598 Uid.Pid p = u.mPids.get(pid);
2599 if (p != null) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002600 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002601 }
2602 }
2603 return 0;
2604 }
2605
2606 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002607 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002608 Uid u = mUidStats.get(uid);
2609 if (u != null) {
2610 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
2611 }
2612 }
2613
Dianne Hackborn287952c2010-09-22 22:34:31 -07002614 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002615 uid = mapUid(uid);
Dianne Hackborn287952c2010-09-22 22:34:31 -07002616 Uid u = mUidStats.get(uid);
2617 if (u != null) {
2618 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
2619 }
2620 }
2621
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002622 int mSensorNesting;
2623
2624 public void noteStartSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002625 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002626 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002627 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002628 if (mSensorNesting == 0) {
2629 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
2630 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
2631 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002632 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002633 }
2634 mSensorNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002635 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002636 }
2637
2638 public void noteStopSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002639 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002640 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002641 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002642 mSensorNesting--;
2643 if (mSensorNesting == 0) {
2644 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
2645 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
2646 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002647 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002648 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002649 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002650 }
2651
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002652 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002653
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002654 public void noteStartGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002655 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002656 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002657 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002658 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002659 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002660 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
2661 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002662 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002663 }
2664 mGpsNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002665 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002667
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002668 public void noteStopGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002669 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002670 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002671 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002672 mGpsNesting--;
2673 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002674 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002675 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
2676 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002677 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002678 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002679 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002681
Jeff Browne95c3cd2014-05-02 16:59:26 -07002682 public void noteScreenStateLocked(int state) {
2683 if (mScreenState != state) {
2684 final int oldState = mScreenState;
2685 mScreenState = state;
2686 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
2687 + ", newState=" + Display.stateToString(state));
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002688
Jeff Browne95c3cd2014-05-02 16:59:26 -07002689 if (state == Display.STATE_ON) {
2690 // Screen turning on.
2691 final long elapsedRealtime = SystemClock.elapsedRealtime();
2692 final long uptime = SystemClock.uptimeMillis();
2693 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
2694 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
2695 + Integer.toHexString(mHistoryCur.states));
2696 addHistoryRecordLocked(elapsedRealtime, uptime);
2697 mScreenOnTimer.startRunningLocked(elapsedRealtime);
2698 if (mScreenBrightnessBin >= 0) {
2699 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
2700 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002701
Jeff Browne95c3cd2014-05-02 16:59:26 -07002702 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false,
2703 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002704
Jeff Browne95c3cd2014-05-02 16:59:26 -07002705 // Fake a wake lock, so we consider the device waked as long
2706 // as the screen is on.
2707 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
2708 elapsedRealtime, uptime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002709
Jeff Browne95c3cd2014-05-02 16:59:26 -07002710 // Update discharge amounts.
2711 if (mOnBatteryInternal) {
2712 updateDischargeScreenLevelsLocked(false, true);
2713 }
2714 } else if (oldState == Display.STATE_ON) {
2715 // Screen turning off or dozing.
2716 final long elapsedRealtime = SystemClock.elapsedRealtime();
2717 final long uptime = SystemClock.uptimeMillis();
2718 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
2719 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
2720 + Integer.toHexString(mHistoryCur.states));
2721 addHistoryRecordLocked(elapsedRealtime, uptime);
2722 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
2723 if (mScreenBrightnessBin >= 0) {
2724 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
2725 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002726
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002727 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL,
Jeff Browne95c3cd2014-05-02 16:59:26 -07002728 elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002729
Jeff Browne95c3cd2014-05-02 16:59:26 -07002730 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
2731 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002732
Jeff Browne95c3cd2014-05-02 16:59:26 -07002733 // Update discharge amounts.
2734 if (mOnBatteryInternal) {
2735 updateDischargeScreenLevelsLocked(true, false);
2736 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08002737 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002738 }
2739 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002740
Dianne Hackborn617f8772009-03-31 15:04:46 -07002741 public void noteScreenBrightnessLocked(int brightness) {
2742 // Bin the brightness.
2743 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
2744 if (bin < 0) bin = 0;
2745 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
2746 if (mScreenBrightnessBin != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002747 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002748 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002749 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
2750 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002751 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
2752 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002753 addHistoryRecordLocked(elapsedRealtime, uptime);
Jeff Browne95c3cd2014-05-02 16:59:26 -07002754 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002755 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002756 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002757 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002758 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002759 }
2760 mScreenBrightnessBin = bin;
2761 }
2762 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002763
Dianne Hackborn617f8772009-03-31 15:04:46 -07002764 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002765 if (mOnBatteryInternal) {
2766 uid = mapUid(uid);
2767 getUidStatsLocked(uid).noteUserActivityLocked(event);
2768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002769 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002770
Jeff Browne95c3cd2014-05-02 16:59:26 -07002771 public void noteInteractiveLocked(boolean interactive) {
2772 if (mInteractive != interactive) {
2773 final long elapsedRealtime = SystemClock.elapsedRealtime();
2774 mInteractive = interactive;
2775 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
2776 if (interactive) {
2777 mInteractiveTimer.startRunningLocked(elapsedRealtime);
2778 } else {
2779 mInteractiveTimer.stopRunningLocked(elapsedRealtime);
2780 }
2781 }
2782 }
2783
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07002784 public void noteMobileRadioPowerState(int powerState, long timestampNs) {
2785 final long elapsedRealtime = SystemClock.elapsedRealtime();
2786 final long uptime = SystemClock.uptimeMillis();
2787 if (mMobileRadioPowerState != powerState) {
2788 long realElapsedRealtimeMs;
2789 final boolean active =
2790 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
2791 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
2792 if (active) {
2793 realElapsedRealtimeMs = elapsedRealtime;
2794 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
2795 } else {
2796 realElapsedRealtimeMs = timestampNs / (1000*1000);
2797 long lastUpdateTimeMs = mMobileRadioActiveTimer.getLastUpdateTimeMs();
2798 if (realElapsedRealtimeMs < lastUpdateTimeMs) {
2799 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
2800 + " is before start time " + lastUpdateTimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002801 realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07002802 } else if (realElapsedRealtimeMs < elapsedRealtime) {
2803 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
2804 - realElapsedRealtimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002805 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07002806 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
2807 }
2808 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
2809 + Integer.toHexString(mHistoryCur.states));
2810 addHistoryRecordLocked(elapsedRealtime, uptime);
2811 mMobileRadioPowerState = powerState;
2812 if (active) {
2813 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
2814 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
2815 } else {
2816 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
2817 updateNetworkActivityLocked(NET_UPDATE_MOBILE, realElapsedRealtimeMs);
2818 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002819 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002820 }
2821 }
2822
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002823 public void noteLowPowerMode(boolean enabled) {
2824 if (mLowPowerModeEnabled != enabled) {
2825 final long elapsedRealtime = SystemClock.elapsedRealtime();
2826 final long uptime = SystemClock.uptimeMillis();
2827 mLowPowerModeEnabled = enabled;
2828 if (enabled) {
2829 mHistoryCur.states2 |= HistoryItem.STATE2_LOW_POWER_FLAG;
2830 if (DEBUG_HISTORY) Slog.v(TAG, "Low power mode enabled to: "
2831 + Integer.toHexString(mHistoryCur.states2));
2832 mLowPowerModeEnabledTimer.startRunningLocked(elapsedRealtime);
2833 } else {
2834 mHistoryCur.states2 &= ~HistoryItem.STATE2_LOW_POWER_FLAG;
2835 if (DEBUG_HISTORY) Slog.v(TAG, "Low power mode disabled to: "
2836 + Integer.toHexString(mHistoryCur.states2));
2837 mLowPowerModeEnabledTimer.stopRunningLocked(elapsedRealtime);
2838 }
2839 addHistoryRecordLocked(elapsedRealtime, uptime);
2840 }
2841 }
2842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 public void notePhoneOnLocked() {
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 on 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 = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002852 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 }
2854 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002856 public void notePhoneOffLocked() {
2857 if (mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002858 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002859 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002860 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002861 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
2862 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07002863 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002864 mPhoneOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002865 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002866 }
2867 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002868
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002869 void stopAllSignalStrengthTimersLocked(int except) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002870 final long elapsedRealtime = SystemClock.elapsedRealtime();
Wink Saville52840902011-02-18 12:40:47 -08002871 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002872 if (i == except) {
2873 continue;
2874 }
2875 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002876 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002877 }
2878 }
2879 }
2880
Dianne Hackborne4a59512010-12-07 11:08:07 -08002881 private int fixPhoneServiceState(int state, int signalBin) {
2882 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
2883 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2884 // to infer that we are scanning from other data.
2885 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08002886 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002887 state = ServiceState.STATE_IN_SERVICE;
2888 }
2889 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002890
Dianne Hackborne4a59512010-12-07 11:08:07 -08002891 return state;
2892 }
2893
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002894 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002895 boolean scanning = false;
2896 boolean newHistory = false;
2897
2898 mPhoneServiceStateRaw = state;
2899 mPhoneSimStateRaw = simState;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002900 mPhoneSignalStrengthBinRaw = strengthBin;
2901
2902 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002903 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne4a59512010-12-07 11:08:07 -08002904
2905 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
2906 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2907 // to infer that we are scanning from other data.
2908 if (state == ServiceState.STATE_OUT_OF_SERVICE
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002909 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002910 state = ServiceState.STATE_IN_SERVICE;
2911 }
2912 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002913
2914 // If the phone is powered off, stop all timers.
2915 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002916 strengthBin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002917
Dianne Hackborne4a59512010-12-07 11:08:07 -08002918 // If we are in service, make sure the correct signal string timer is running.
2919 } else if (state == ServiceState.STATE_IN_SERVICE) {
2920 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002921
2922 // If we're out of service, we are in the lowest signal strength
2923 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07002924 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002925 scanning = true;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002926 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002927 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002928 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08002929 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002930 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
2931 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002932 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
Amith Yamasanif37447b2009-10-08 18:28:01 -07002933 }
2934 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002935
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002936 if (!scanning) {
2937 // If we are no longer scanning, then stop the scanning timer.
2938 if (mPhoneSignalScanningTimer.isRunningLocked()) {
2939 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
2940 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
2941 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002942 newHistory = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002943 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002944 }
2945 }
2946
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002947 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002948 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
2949 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002950 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002951 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002952 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002953 mPhoneServiceState = state;
2954 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08002955
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002956 if (mPhoneSignalStrengthBin != strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002957 if (mPhoneSignalStrengthBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002958 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002959 elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002960 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002961 if (strengthBin >= 0) {
2962 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002963 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002964 }
2965 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002966 | (strengthBin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
2967 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
Dianne Hackborne4a59512010-12-07 11:08:07 -08002968 + Integer.toHexString(mHistoryCur.states));
2969 newHistory = true;
2970 } else {
2971 stopAllSignalStrengthTimersLocked(-1);
2972 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002973 mPhoneSignalStrengthBin = strengthBin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08002974 }
2975
2976 if (newHistory) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002977 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002978 }
2979 }
2980
2981 /**
2982 * Telephony stack updates the phone state.
2983 * @param state phone state from ServiceState.getState()
2984 */
2985 public void notePhoneStateLocked(int state, int simState) {
2986 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002987 }
2988
Wink Savillee9b06d72009-05-18 21:47:50 -07002989 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07002990 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08002991 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08002992 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002993 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002994
Dianne Hackborn627bba72009-03-24 22:32:56 -07002995 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
2996 int bin = DATA_CONNECTION_NONE;
2997 if (hasData) {
2998 switch (dataType) {
2999 case TelephonyManager.NETWORK_TYPE_EDGE:
3000 bin = DATA_CONNECTION_EDGE;
3001 break;
3002 case TelephonyManager.NETWORK_TYPE_GPRS:
3003 bin = DATA_CONNECTION_GPRS;
3004 break;
3005 case TelephonyManager.NETWORK_TYPE_UMTS:
3006 bin = DATA_CONNECTION_UMTS;
3007 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003008 case TelephonyManager.NETWORK_TYPE_CDMA:
3009 bin = DATA_CONNECTION_CDMA;
3010 break;
3011 case TelephonyManager.NETWORK_TYPE_EVDO_0:
3012 bin = DATA_CONNECTION_EVDO_0;
3013 break;
3014 case TelephonyManager.NETWORK_TYPE_EVDO_A:
3015 bin = DATA_CONNECTION_EVDO_A;
3016 break;
3017 case TelephonyManager.NETWORK_TYPE_1xRTT:
3018 bin = DATA_CONNECTION_1xRTT;
3019 break;
3020 case TelephonyManager.NETWORK_TYPE_HSDPA:
3021 bin = DATA_CONNECTION_HSDPA;
3022 break;
3023 case TelephonyManager.NETWORK_TYPE_HSUPA:
3024 bin = DATA_CONNECTION_HSUPA;
3025 break;
3026 case TelephonyManager.NETWORK_TYPE_HSPA:
3027 bin = DATA_CONNECTION_HSPA;
3028 break;
3029 case TelephonyManager.NETWORK_TYPE_IDEN:
3030 bin = DATA_CONNECTION_IDEN;
3031 break;
3032 case TelephonyManager.NETWORK_TYPE_EVDO_B:
3033 bin = DATA_CONNECTION_EVDO_B;
3034 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07003035 case TelephonyManager.NETWORK_TYPE_LTE:
3036 bin = DATA_CONNECTION_LTE;
3037 break;
3038 case TelephonyManager.NETWORK_TYPE_EHRPD:
3039 bin = DATA_CONNECTION_EHRPD;
3040 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08003041 case TelephonyManager.NETWORK_TYPE_HSPAP:
3042 bin = DATA_CONNECTION_HSPAP;
3043 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07003044 default:
3045 bin = DATA_CONNECTION_OTHER;
3046 break;
3047 }
3048 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003049 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003050 if (mPhoneDataConnectionType != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003051 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003052 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003053 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
3054 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003055 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
3056 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003057 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003058 if (mPhoneDataConnectionType >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003059 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003060 elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003061 }
3062 mPhoneDataConnectionType = bin;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003063 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003064 }
3065 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003066
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003067 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07003068 if (!mWifiOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003069 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003070 final long uptime = SystemClock.uptimeMillis();
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 on 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 = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003076 mWifiOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003077 }
3078 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003079
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003080 public void noteWifiOffLocked() {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003081 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003082 final long uptime = SystemClock.uptimeMillis();
The Android Open Source Project10592532009-03-18 17:39:46 -07003083 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003084 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003085 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
3086 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003087 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003088 mWifiOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003089 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003090 }
3091 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003092
3093 public void noteAudioOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003094 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003095 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003096 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003097 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003098 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003099 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
3100 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003101 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003102 mAudioOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003103 mAudioOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003104 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003105 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003106 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003107
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003108 public void noteAudioOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003109 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003110 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003111 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003112 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003113 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003114 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3115 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003116 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003117 mAudioOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003118 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003119 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003120 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003121 }
3122
3123 public void noteVideoOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003124 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003125 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003126 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003127 if (!mVideoOn) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003128 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003129 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
3130 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003131 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003132 mVideoOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003133 mVideoOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003134 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003135 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003136 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003137
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003138 public void noteVideoOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003139 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003140 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003141 final long uptime = SystemClock.uptimeMillis();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003142 if (mVideoOn) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003143 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003144 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3145 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003146 addHistoryRecordLocked(elapsedRealtime, uptime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003147 mVideoOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003148 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003149 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003150 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003151 }
3152
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003153 public void noteActivityResumedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003154 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003155 getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003156 }
3157
3158 public void noteActivityPausedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003159 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003160 getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003161 }
3162
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003163 public void noteVibratorOnLocked(int uid, long durationMillis) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003164 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003165 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
3166 }
3167
3168 public void noteVibratorOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003169 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003170 getUidStatsLocked(uid).noteVibratorOffLocked();
3171 }
3172
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003173 public void noteWifiRunningLocked(WorkSource ws) {
3174 if (!mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003175 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003176 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003177 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003178 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
3179 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003180 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003181 mGlobalWifiRunning = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003182 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003183 int N = ws.size();
3184 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003185 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003186 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003187 }
3188 } else {
3189 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003190 }
3191 }
3192
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003193 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
3194 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003195 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003196 int N = oldWs.size();
3197 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003198 int uid = mapUid(oldWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003199 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003200 }
3201 N = newWs.size();
3202 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003203 int uid = mapUid(newWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003204 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003205 }
3206 } else {
3207 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
3208 }
3209 }
3210
3211 public void noteWifiStoppedLocked(WorkSource ws) {
3212 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003213 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003214 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003215 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003216 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
3217 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003218 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003219 mGlobalWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003220 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003221 int N = ws.size();
3222 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003223 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003224 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003225 }
3226 } else {
3227 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003228 }
3229 }
3230
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003231 public void noteWifiStateLocked(int wifiState, String accessPoint) {
3232 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
3233 if (mWifiState != wifiState) {
3234 final long elapsedRealtime = SystemClock.elapsedRealtime();
3235 if (mWifiState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003236 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003237 }
3238 mWifiState = wifiState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003239 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003240 }
3241 }
3242
The Android Open Source Project10592532009-03-18 17:39:46 -07003243 public void noteBluetoothOnLocked() {
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 on 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 = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003252 mBluetoothOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003253 }
3254 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003255
The Android Open Source Project10592532009-03-18 17:39:46 -07003256 public void noteBluetoothOffLocked() {
3257 if (mBluetoothOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003258 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003259 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003260 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003261 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
3262 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003263 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003264 mBluetoothOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003265 mBluetoothOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003266 }
3267 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003268
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003269 public void noteBluetoothStateLocked(int bluetoothState) {
3270 if (DEBUG) Log.i(TAG, "Bluetooth state -> " + bluetoothState);
3271 if (mBluetoothState != bluetoothState) {
3272 final long elapsedRealtime = SystemClock.elapsedRealtime();
3273 if (mBluetoothState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003274 mBluetoothStateTimer[mBluetoothState].stopRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003275 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003276 mBluetoothState = bluetoothState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003277 mBluetoothStateTimer[bluetoothState].startRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003278 }
3279 }
3280
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003281 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003282
The Android Open Source Project10592532009-03-18 17:39:46 -07003283 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003284 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003285 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003286 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003287 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003288 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003289 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
3290 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003291 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003292 }
3293 mWifiFullLockNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003294 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003295 }
3296
3297 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003298 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003299 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003300 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003301 mWifiFullLockNesting--;
3302 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003303 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003304 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
3305 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003306 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003307 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003308 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003309 }
3310
Nick Pelly6ccaa542012-06-15 15:22:47 -07003311 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003312
Nick Pelly6ccaa542012-06-15 15:22:47 -07003313 public void noteWifiScanStartedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003314 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003315 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003316 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003317 if (mWifiScanNesting == 0) {
3318 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
3319 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003320 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003321 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003322 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003323 mWifiScanNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003324 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003325 }
3326
Nick Pelly6ccaa542012-06-15 15:22:47 -07003327 public void noteWifiScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003328 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003329 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003330 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003331 mWifiScanNesting--;
3332 if (mWifiScanNesting == 0) {
3333 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
3334 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003335 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003336 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003337 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003338 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003339 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003340
Robert Greenwalta029ea12013-09-25 16:38:12 -07003341 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003342 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003343 final long elapsedRealtime = SystemClock.elapsedRealtime();
3344 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003345 }
3346
3347 public void noteWifiBatchedScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003348 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003349 final long elapsedRealtime = SystemClock.elapsedRealtime();
3350 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003351 }
3352
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003353 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003354
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003355 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003356 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003357 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003358 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003359 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003360 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003361 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
3362 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003363 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003364 }
3365 mWifiMulticastNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003366 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003367 }
3368
3369 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003370 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003371 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003372 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003373 mWifiMulticastNesting--;
3374 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003375 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003376 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
3377 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003378 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003379 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003380 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003381 }
3382
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003383 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
3384 int N = ws.size();
3385 for (int i=0; i<N; i++) {
3386 noteFullWifiLockAcquiredLocked(ws.get(i));
3387 }
3388 }
3389
3390 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
3391 int N = ws.size();
3392 for (int i=0; i<N; i++) {
3393 noteFullWifiLockReleasedLocked(ws.get(i));
3394 }
3395 }
3396
Nick Pelly6ccaa542012-06-15 15:22:47 -07003397 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003398 int N = ws.size();
3399 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003400 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003401 }
3402 }
3403
Nick Pelly6ccaa542012-06-15 15:22:47 -07003404 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003405 int N = ws.size();
3406 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003407 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003408 }
3409 }
3410
Robert Greenwalta029ea12013-09-25 16:38:12 -07003411 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
3412 int N = ws.size();
3413 for (int i=0; i<N; i++) {
3414 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
3415 }
3416 }
3417
3418 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
3419 int N = ws.size();
3420 for (int i=0; i<N; i++) {
3421 noteWifiBatchedScanStoppedLocked(ws.get(i));
3422 }
3423 }
3424
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003425 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
3426 int N = ws.size();
3427 for (int i=0; i<N; i++) {
3428 noteWifiMulticastEnabledLocked(ws.get(i));
3429 }
3430 }
3431
3432 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
3433 int N = ws.size();
3434 for (int i=0; i<N; i++) {
3435 noteWifiMulticastDisabledLocked(ws.get(i));
3436 }
3437 }
3438
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003439 private static String[] includeInStringArray(String[] array, String str) {
3440 if (ArrayUtils.indexOf(array, str) >= 0) {
3441 return array;
3442 }
3443 String[] newArray = new String[array.length+1];
3444 System.arraycopy(array, 0, newArray, 0, array.length);
3445 newArray[array.length] = str;
3446 return newArray;
3447 }
3448
3449 private static String[] excludeFromStringArray(String[] array, String str) {
3450 int index = ArrayUtils.indexOf(array, str);
3451 if (index >= 0) {
3452 String[] newArray = new String[array.length-1];
3453 if (index > 0) {
3454 System.arraycopy(array, 0, newArray, 0, index);
3455 }
3456 if (index < array.length-1) {
3457 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
3458 }
3459 return newArray;
3460 }
3461 return array;
3462 }
3463
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003464 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
3465 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003466 mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
3467 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003468 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003469 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
3470 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003471 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003472 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003473 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
3474 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003475 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08003476 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
3477 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003478 }
3479 }
3480
3481 public void noteNetworkStatsEnabledLocked() {
3482 // During device boot, qtaguid isn't enabled until after the inital
3483 // loading of battery stats. Now that they're enabled, take our initial
3484 // snapshot for future delta calculation.
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003485 updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003486 }
3487
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003488 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
3489 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003490 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003491
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003492 @Override public int getScreenOnCount(int which) {
3493 return mScreenOnTimer.getCountLocked(which);
3494 }
3495
Dianne Hackborn617f8772009-03-31 15:04:46 -07003496 @Override public long getScreenBrightnessTime(int brightnessBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003497 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003498 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003499 elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003500 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003501
Jeff Browne95c3cd2014-05-02 16:59:26 -07003502 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
3503 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003504 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003505
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003506 @Override public long getLowPowerModeEnabledTime(long elapsedRealtimeUs, int which) {
3507 return mLowPowerModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
3508 }
3509
3510 @Override public int getLowPowerModeEnabledCount(int which) {
3511 return mLowPowerModeEnabledTimer.getCountLocked(which);
3512 }
3513
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003514 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
3515 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003516 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003517
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003518 @Override public int getPhoneOnCount(int which) {
3519 return mPhoneOnTimer.getCountLocked(which);
3520 }
3521
Dianne Hackborn627bba72009-03-24 22:32:56 -07003522 @Override public long getPhoneSignalStrengthTime(int strengthBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003523 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003524 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003525 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003526 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003527
3528 @Override public long getPhoneSignalScanningTime(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003529 long elapsedRealtimeUs, int which) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07003530 return mPhoneSignalScanningTimer.getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003531 elapsedRealtimeUs, which);
Amith Yamasanif37447b2009-10-08 18:28:01 -07003532 }
3533
Catherine Liufb900812012-07-17 14:12:56 -05003534 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
3535 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003536 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003537
Dianne Hackborn627bba72009-03-24 22:32:56 -07003538 @Override public long getPhoneDataConnectionTime(int dataType,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003539 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003540 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003541 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003542 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003543
Dianne Hackborn617f8772009-03-31 15:04:46 -07003544 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07003545 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003546 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003547
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003548 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
3549 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003550 }
3551
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003552 @Override public int getMobileRadioActiveCount(int which) {
3553 return mMobileRadioActiveTimer.getCountLocked(which);
3554 }
3555
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003556 @Override public long getMobileRadioActiveAdjustedTime(int which) {
3557 return mMobileRadioActiveAdjustedTime.getCountLocked(which);
3558 }
3559
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003560 @Override public long getMobileRadioActiveUnknownTime(int which) {
3561 return mMobileRadioActiveUnknownTime.getCountLocked(which);
3562 }
3563
3564 @Override public int getMobileRadioActiveUnknownCount(int which) {
3565 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
3566 }
3567
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003568 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
3569 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003570 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003571
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003572 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
3573 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003574 }
3575
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003576 @Override public long getWifiStateTime(int wifiState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003577 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003578 return mWifiStateTimer[wifiState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003579 elapsedRealtimeUs, which);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003580 }
3581
3582 @Override public int getWifiStateCount(int wifiState, int which) {
3583 return mWifiStateTimer[wifiState].getCountLocked(which);
3584 }
3585
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003586 @Override public long getBluetoothOnTime(long elapsedRealtimeUs, int which) {
3587 return mBluetoothOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003588 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003589
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003590 @Override public long getBluetoothStateTime(int bluetoothState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003591 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003592 return mBluetoothStateTimer[bluetoothState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003593 elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003594 }
3595
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003596 @Override public int getBluetoothStateCount(int bluetoothState, int which) {
3597 return mBluetoothStateTimer[bluetoothState].getCountLocked(which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003598 }
3599
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003600 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003601 public long getNetworkActivityBytes(int type, int which) {
3602 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
3603 return mNetworkByteActivityCounters[type].getCountLocked(which);
3604 } else {
3605 return 0;
3606 }
3607 }
3608
3609 @Override
3610 public long getNetworkActivityPackets(int type, int which) {
3611 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
3612 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003613 } else {
3614 return 0;
3615 }
3616 }
3617
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08003618 @Override public long getStartClockTime() {
3619 return mStartClockTime;
3620 }
3621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 @Override public boolean getIsOnBattery() {
3623 return mOnBattery;
3624 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003626 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
3627 return mUidStats;
3628 }
3629
3630 /**
3631 * The statistics associated with a particular uid.
3632 */
3633 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003636
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003637 boolean mWifiRunning;
3638 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003639
The Android Open Source Project10592532009-03-18 17:39:46 -07003640 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07003641 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003642
Nick Pelly6ccaa542012-06-15 15:22:47 -07003643 boolean mWifiScanStarted;
3644 StopwatchTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003645
Robert Greenwalta029ea12013-09-25 16:38:12 -07003646 private static final int NO_BATCHED_SCAN_STARTED = -1;
3647 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
3648 StopwatchTimer[] mWifiBatchedScanTimer;
3649
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003650 boolean mWifiMulticastEnabled;
3651 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003652
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003653 boolean mAudioTurnedOn;
3654 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003655
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003656 boolean mVideoTurnedOn;
3657 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003658
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003659 StopwatchTimer mForegroundActivityTimer;
3660
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003661 BatchTimer mVibratorOnTimer;
3662
Dianne Hackborn617f8772009-03-31 15:04:46 -07003663 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003664
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003665 LongSamplingCounter[] mNetworkByteActivityCounters;
3666 LongSamplingCounter[] mNetworkPacketActivityCounters;
Dianne Hackbornd45665b2014-02-26 12:35:32 -08003667 LongSamplingCounter mMobileRadioActiveTime;
3668 LongSamplingCounter mMobileRadioActiveCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 /**
3671 * The statistics we have collected for this uid's wake locks.
3672 */
3673 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
3674
3675 /**
3676 * The statistics we have collected for this uid's sensor activations.
3677 */
3678 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
3679
3680 /**
3681 * The statistics we have collected for this uid's processes.
3682 */
3683 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
3684
3685 /**
3686 * The statistics we have collected for this uid's processes.
3687 */
3688 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003689
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003690 /**
3691 * The transient wake stats we have collected for this uid's pids.
3692 */
3693 final SparseArray<Pid> mPids = new SparseArray<Pid>();
3694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003695 public Uid(int uid) {
3696 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003697 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003698 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003699 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003700 mFullWifiLockTimers, mOnBatteryTimeBase);
Nick Pelly6ccaa542012-06-15 15:22:47 -07003701 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003702 mWifiScanTimers, mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003703 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003704 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003705 mWifiMulticastTimers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003706 }
3707
3708 @Override
3709 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
3710 return mWakelockStats;
3711 }
3712
3713 @Override
3714 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
3715 return mSensorStats;
3716 }
3717
3718 @Override
3719 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
3720 return mProcessStats;
3721 }
3722
3723 @Override
3724 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
3725 return mPackageStats;
3726 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003727
3728 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003729 public int getUid() {
3730 return mUid;
3731 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003732
3733 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003734 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003735 if (!mWifiRunning) {
3736 mWifiRunning = true;
3737 if (mWifiRunningTimer == null) {
3738 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003739 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003740 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003741 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003742 }
3743 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003744
Dianne Hackborn617f8772009-03-31 15:04:46 -07003745 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003746 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003747 if (mWifiRunning) {
3748 mWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003749 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003750 }
3751 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003752
Dianne Hackborn617f8772009-03-31 15:04:46 -07003753 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003754 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003755 if (!mFullWifiLockOut) {
3756 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003757 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003758 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003759 mFullWifiLockTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003760 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003761 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003762 }
3763 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003764
The Android Open Source Project10592532009-03-18 17:39:46 -07003765 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003766 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003767 if (mFullWifiLockOut) {
3768 mFullWifiLockOut = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003769 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003770 }
3771 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003772
The Android Open Source Project10592532009-03-18 17:39:46 -07003773 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003774 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003775 if (!mWifiScanStarted) {
3776 mWifiScanStarted = true;
3777 if (mWifiScanTimer == null) {
3778 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003779 mWifiScanTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003780 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003781 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003782 }
3783 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003784
The Android Open Source Project10592532009-03-18 17:39:46 -07003785 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003786 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003787 if (mWifiScanStarted) {
3788 mWifiScanStarted = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003789 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07003790 }
3791 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003792
3793 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003794 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07003795 int bin = 0;
3796 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
3797 csph = csph >> 3;
3798 bin++;
3799 }
3800
3801 if (mWifiBatchedScanBinStarted == bin) return;
3802
3803 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 }
3807 mWifiBatchedScanBinStarted = bin;
3808 if (mWifiBatchedScanTimer[bin] == null) {
3809 makeWifiBatchedScanBin(bin, null);
3810 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003811 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003812 }
3813
3814 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003815 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07003816 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
3817 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003818 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003819 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
3820 }
3821 }
3822
3823 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003824 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003825 if (!mWifiMulticastEnabled) {
3826 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003827 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003828 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003829 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003830 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003831 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003832 }
3833 }
3834
3835 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003836 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003837 if (mWifiMulticastEnabled) {
3838 mWifiMulticastEnabled = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003839 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003840 }
3841 }
3842
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003843 public StopwatchTimer createAudioTurnedOnTimerLocked() {
3844 if (mAudioTurnedOnTimer == null) {
3845 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003846 null, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003847 }
3848 return mAudioTurnedOnTimer;
3849 }
3850
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003851 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003852 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003853 if (!mAudioTurnedOn) {
3854 mAudioTurnedOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003855 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003856 }
3857 }
3858
3859 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003860 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003861 if (mAudioTurnedOn) {
3862 mAudioTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003863 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003864 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003865 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003866 }
3867 }
3868
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003869 public StopwatchTimer createVideoTurnedOnTimerLocked() {
3870 if (mVideoTurnedOnTimer == null) {
3871 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003872 null, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003873 }
3874 return mVideoTurnedOnTimer;
3875 }
3876
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003877 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003878 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003879 if (!mVideoTurnedOn) {
3880 mVideoTurnedOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003881 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003882 }
3883 }
3884
3885 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003886 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003887 if (mVideoTurnedOn) {
3888 mVideoTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003889 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003890 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003891 }
3892 }
3893 }
3894
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003895 public StopwatchTimer createForegroundActivityTimerLocked() {
3896 if (mForegroundActivityTimer == null) {
3897 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003898 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003899 }
3900 return mForegroundActivityTimer;
3901 }
3902
3903 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003904 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003905 // We always start, since we want multiple foreground PIDs to nest
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003906 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003907 }
3908
3909 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003910 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003911 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003912 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003913 }
3914 }
3915
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003916 public BatchTimer createVibratorOnTimerLocked() {
3917 if (mVibratorOnTimer == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003918 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003919 }
3920 return mVibratorOnTimer;
3921 }
3922
3923 public void noteVibratorOnLocked(long durationMillis) {
3924 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
3925 }
3926
3927 public void noteVibratorOffLocked() {
3928 if (mVibratorOnTimer != null) {
3929 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003930 }
3931 }
3932
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003933 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003934 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003935 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003936 return 0;
3937 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003938 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003939 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003940
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003941 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003942 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003943 if (mFullWifiLockTimer == null) {
3944 return 0;
3945 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003946 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003947 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003948
3949 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003950 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003951 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003952 return 0;
3953 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003954 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07003955 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003956
3957 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003958 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07003959 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
3960 if (mWifiBatchedScanTimer[csphBin] == null) {
3961 return 0;
3962 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003963 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003964 }
3965
3966 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003967 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003968 if (mWifiMulticastTimer == null) {
3969 return 0;
3970 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003971 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003972 }
3973
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003974 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003975 public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003976 if (mAudioTurnedOnTimer == null) {
3977 return 0;
3978 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003979 return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003980 }
3981
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003982 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003983 public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003984 if (mVideoTurnedOnTimer == null) {
3985 return 0;
3986 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003987 return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003988 }
3989
Dianne Hackborn617f8772009-03-31 15:04:46 -07003990 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003991 public Timer getForegroundActivityTimer() {
3992 return mForegroundActivityTimer;
3993 }
3994
3995 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003996 public Timer getVibratorOnTimer() {
3997 return mVibratorOnTimer;
3998 }
3999
4000 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07004001 public void noteUserActivityLocked(int type) {
4002 if (mUserActivityCounters == null) {
4003 initUserActivityLocked();
4004 }
Jeff Browndf693de2012-07-27 12:03:38 -07004005 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
4006 mUserActivityCounters[type].stepAtomic();
4007 } else {
4008 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
4009 new Throwable());
4010 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07004011 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004012
Dianne Hackborn617f8772009-03-31 15:04:46 -07004013 @Override
4014 public boolean hasUserActivity() {
4015 return mUserActivityCounters != null;
4016 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004017
Dianne Hackborn617f8772009-03-31 15:04:46 -07004018 @Override
4019 public int getUserActivityCount(int type, int which) {
4020 if (mUserActivityCounters == null) {
4021 return 0;
4022 }
Evan Millarc64edde2009-04-18 12:26:32 -07004023 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004024 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004025
Robert Greenwalta029ea12013-09-25 16:38:12 -07004026 void makeWifiBatchedScanBin(int i, Parcel in) {
4027 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
4028
4029 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i);
4030 if (collected == null) {
4031 collected = new ArrayList<StopwatchTimer>();
4032 mWifiBatchedScanTimers.put(i, collected);
4033 }
4034 if (in == null) {
4035 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004036 mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004037 } else {
4038 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004039 mOnBatteryTimeBase, in);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004040 }
4041 }
4042
4043
Dianne Hackborn617f8772009-03-31 15:04:46 -07004044 void initUserActivityLocked() {
4045 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
4046 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004047 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004048 }
4049 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004050
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004051 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
4052 if (mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004053 initNetworkActivityLocked();
4054 }
4055 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004056 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
4057 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004058 } else {
4059 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
4060 new Throwable());
4061 }
4062 }
4063
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004064 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
4065 if (mNetworkByteActivityCounters == null) {
4066 initNetworkActivityLocked();
4067 }
4068 mMobileRadioActiveTime.addCountLocked(batteryUptime);
4069 mMobileRadioActiveCount.addCountLocked(1);
4070 }
4071
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004072 @Override
4073 public boolean hasNetworkActivity() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004074 return mNetworkByteActivityCounters != null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004075 }
4076
4077 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004078 public long getNetworkActivityBytes(int type, int which) {
4079 if (mNetworkByteActivityCounters != null && type >= 0
4080 && type < mNetworkByteActivityCounters.length) {
4081 return mNetworkByteActivityCounters[type].getCountLocked(which);
4082 } else {
4083 return 0;
4084 }
4085 }
4086
4087 @Override
4088 public long getNetworkActivityPackets(int type, int which) {
4089 if (mNetworkPacketActivityCounters != null && type >= 0
4090 && type < mNetworkPacketActivityCounters.length) {
4091 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004092 } else {
4093 return 0;
4094 }
4095 }
4096
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004097 @Override
4098 public long getMobileRadioActiveTime(int which) {
4099 return mMobileRadioActiveTime != null
4100 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
4101 }
4102
4103 @Override
4104 public int getMobileRadioActiveCount(int which) {
4105 return mMobileRadioActiveCount != null
4106 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
4107 }
4108
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004109 void initNetworkActivityLocked() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004110 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
4111 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004112 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004113 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
4114 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004115 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004116 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase);
4117 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004118 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004119
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004120 /**
4121 * Clear all stats for this uid. Returns true if the uid is completely
4122 * inactive so can be dropped.
4123 */
4124 boolean reset() {
4125 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004126
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004127 if (mWifiRunningTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004128 active |= !mWifiRunningTimer.reset(false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004129 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004130 }
4131 if (mFullWifiLockTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004132 active |= !mFullWifiLockTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004133 active |= mFullWifiLockOut;
4134 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004135 if (mWifiScanTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004136 active |= !mWifiScanTimer.reset(false);
Nick Pelly6ccaa542012-06-15 15:22:47 -07004137 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004138 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004139 if (mWifiBatchedScanTimer != null) {
4140 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4141 if (mWifiBatchedScanTimer[i] != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004142 active |= !mWifiBatchedScanTimer[i].reset(false);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004143 }
4144 }
4145 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
4146 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004147 if (mWifiMulticastTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004148 active |= !mWifiMulticastTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004149 active |= mWifiMulticastEnabled;
4150 }
4151 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004152 active |= !mAudioTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004153 active |= mAudioTurnedOn;
4154 }
4155 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004156 active |= !mVideoTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004157 active |= mVideoTurnedOn;
4158 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004159 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004160 active |= !mForegroundActivityTimer.reset(false);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004161 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004162 if (mVibratorOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004163 if (mVibratorOnTimer.reset(false)) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004164 mVibratorOnTimer.detach();
4165 mVibratorOnTimer = null;
4166 } else {
4167 active = true;
4168 }
4169 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004170
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004171 if (mUserActivityCounters != null) {
4172 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
4173 mUserActivityCounters[i].reset(false);
4174 }
4175 }
4176
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004177 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004178 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004179 mNetworkByteActivityCounters[i].reset(false);
4180 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004181 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004182 mMobileRadioActiveTime.reset(false);
4183 mMobileRadioActiveCount.reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004184 }
4185
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004186 if (mWakelockStats.size() > 0) {
4187 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
4188 while (it.hasNext()) {
4189 Map.Entry<String, Wakelock> wakelockEntry = it.next();
4190 Wakelock wl = wakelockEntry.getValue();
4191 if (wl.reset()) {
4192 it.remove();
4193 } else {
4194 active = true;
4195 }
4196 }
4197 }
4198 if (mSensorStats.size() > 0) {
4199 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
4200 while (it.hasNext()) {
4201 Map.Entry<Integer, Sensor> sensorEntry = it.next();
4202 Sensor s = sensorEntry.getValue();
4203 if (s.reset()) {
4204 it.remove();
4205 } else {
4206 active = true;
4207 }
4208 }
4209 }
4210 if (mProcessStats.size() > 0) {
4211 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
4212 while (it.hasNext()) {
4213 Map.Entry<String, Proc> procEntry = it.next();
4214 procEntry.getValue().detach();
4215 }
4216 mProcessStats.clear();
4217 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004218 if (mPids.size() > 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004219 for (int i=mPids.size()-1; i>=0; i--) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004220 Pid pid = mPids.valueAt(i);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004221 if (pid.mWakeNesting > 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004222 active = true;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004223 } else {
4224 mPids.removeAt(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004225 }
4226 }
4227 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004228 if (mPackageStats.size() > 0) {
4229 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
4230 while (it.hasNext()) {
4231 Map.Entry<String, Pkg> pkgEntry = it.next();
4232 Pkg p = pkgEntry.getValue();
4233 p.detach();
4234 if (p.mServiceStats.size() > 0) {
4235 Iterator<Map.Entry<String, Pkg.Serv>> it2
4236 = p.mServiceStats.entrySet().iterator();
4237 while (it2.hasNext()) {
4238 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
4239 servEntry.getValue().detach();
4240 }
4241 }
4242 }
4243 mPackageStats.clear();
4244 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004245
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004246 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004247 if (mWifiRunningTimer != null) {
4248 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004249 }
4250 if (mFullWifiLockTimer != null) {
4251 mFullWifiLockTimer.detach();
4252 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004253 if (mWifiScanTimer != null) {
4254 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004255 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004256 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4257 if (mWifiBatchedScanTimer[i] != null) {
4258 mWifiBatchedScanTimer[i].detach();
4259 }
4260 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004261 if (mWifiMulticastTimer != null) {
4262 mWifiMulticastTimer.detach();
4263 }
4264 if (mAudioTurnedOnTimer != null) {
4265 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004266 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004267 }
4268 if (mVideoTurnedOnTimer != null) {
4269 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004270 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004271 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004272 if (mForegroundActivityTimer != null) {
4273 mForegroundActivityTimer.detach();
4274 mForegroundActivityTimer = null;
4275 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004276 if (mUserActivityCounters != null) {
4277 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
4278 mUserActivityCounters[i].detach();
4279 }
4280 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004281 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004282 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004283 mNetworkByteActivityCounters[i].detach();
4284 mNetworkPacketActivityCounters[i].detach();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004285 }
4286 }
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004287 mPids.clear();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004288 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004289
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004290 return !active;
4291 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004292
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004293 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004294 out.writeInt(mWakelockStats.size());
4295 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
4296 out.writeString(wakelockEntry.getKey());
4297 Uid.Wakelock wakelock = wakelockEntry.getValue();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004298 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 }
4300
4301 out.writeInt(mSensorStats.size());
4302 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
4303 out.writeInt(sensorEntry.getKey());
4304 Uid.Sensor sensor = sensorEntry.getValue();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004305 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 }
4307
4308 out.writeInt(mProcessStats.size());
4309 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
4310 out.writeString(procEntry.getKey());
4311 Uid.Proc proc = procEntry.getValue();
4312 proc.writeToParcelLocked(out);
4313 }
4314
4315 out.writeInt(mPackageStats.size());
4316 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
4317 out.writeString(pkgEntry.getKey());
4318 Uid.Pkg pkg = pkgEntry.getValue();
4319 pkg.writeToParcelLocked(out);
4320 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004321
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004322 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004323 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004324 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004325 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004326 out.writeInt(0);
4327 }
4328 if (mFullWifiLockTimer != null) {
4329 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004330 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004331 } else {
4332 out.writeInt(0);
4333 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004334 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004335 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004336 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004337 } else {
4338 out.writeInt(0);
4339 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004340 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4341 if (mWifiBatchedScanTimer[i] != null) {
4342 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004343 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004344 } else {
4345 out.writeInt(0);
4346 }
4347 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004348 if (mWifiMulticastTimer != null) {
4349 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004350 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004351 } else {
4352 out.writeInt(0);
4353 }
4354 if (mAudioTurnedOnTimer != null) {
4355 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004356 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004357 } else {
4358 out.writeInt(0);
4359 }
4360 if (mVideoTurnedOnTimer != null) {
4361 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004362 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004363 } else {
4364 out.writeInt(0);
4365 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004366 if (mForegroundActivityTimer != null) {
4367 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004368 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004369 } else {
4370 out.writeInt(0);
4371 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004372 if (mVibratorOnTimer != null) {
4373 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004374 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004375 } else {
4376 out.writeInt(0);
4377 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004378 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07004379 out.writeInt(1);
4380 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
4381 mUserActivityCounters[i].writeToParcel(out);
4382 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004383 } else {
4384 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004385 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004386 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004387 out.writeInt(1);
4388 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004389 mNetworkByteActivityCounters[i].writeToParcel(out);
4390 mNetworkPacketActivityCounters[i].writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004391 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004392 mMobileRadioActiveTime.writeToParcel(out);
4393 mMobileRadioActiveCount.writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004394 } else {
4395 out.writeInt(0);
4396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 }
4398
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004399 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004400 int numWakelocks = in.readInt();
4401 mWakelockStats.clear();
4402 for (int j = 0; j < numWakelocks; j++) {
4403 String wakelockName = in.readString();
4404 Uid.Wakelock wakelock = new Wakelock();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004405 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
Dianne Hackbornc24ab862011-10-18 15:55:03 -07004406 // We will just drop some random set of wakelocks if
4407 // the previous run of the system was an older version
4408 // that didn't impose a limit.
4409 mWakelockStats.put(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 }
4411
4412 int numSensors = in.readInt();
4413 mSensorStats.clear();
4414 for (int k = 0; k < numSensors; k++) {
4415 int sensorNumber = in.readInt();
4416 Uid.Sensor sensor = new Sensor(sensorNumber);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004417 sensor.readFromParcelLocked(mOnBatteryTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004418 mSensorStats.put(sensorNumber, sensor);
4419 }
4420
4421 int numProcs = in.readInt();
4422 mProcessStats.clear();
4423 for (int k = 0; k < numProcs; k++) {
4424 String processName = in.readString();
4425 Uid.Proc proc = new Proc();
4426 proc.readFromParcelLocked(in);
4427 mProcessStats.put(processName, proc);
4428 }
4429
4430 int numPkgs = in.readInt();
4431 mPackageStats.clear();
4432 for (int l = 0; l < numPkgs; l++) {
4433 String packageName = in.readString();
4434 Uid.Pkg pkg = new Pkg();
4435 pkg.readFromParcelLocked(in);
4436 mPackageStats.put(packageName, pkg);
4437 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004438
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004439 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004440 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004441 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004442 mWifiRunningTimers, mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004443 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004444 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004445 }
4446 mFullWifiLockOut = false;
4447 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004448 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004449 mFullWifiLockTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004450 } else {
4451 mFullWifiLockTimer = null;
4452 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004453 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004454 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004455 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004456 mWifiScanTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004457 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004458 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004459 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004460 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4461 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4462 if (in.readInt() != 0) {
4463 makeWifiBatchedScanBin(i, in);
4464 } else {
4465 mWifiBatchedScanTimer[i] = null;
4466 }
4467 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004468 mWifiMulticastEnabled = false;
4469 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004470 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004471 mWifiMulticastTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004472 } else {
4473 mWifiMulticastTimer = null;
4474 }
4475 mAudioTurnedOn = false;
4476 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004477 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004478 null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004479 } else {
4480 mAudioTurnedOnTimer = null;
4481 }
4482 mVideoTurnedOn = false;
4483 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004484 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004485 null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004486 } else {
4487 mVideoTurnedOnTimer = null;
4488 }
4489 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004490 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004491 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004492 } else {
4493 mForegroundActivityTimer = null;
4494 }
4495 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004496 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004497 } else {
4498 mVibratorOnTimer = null;
4499 }
4500 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07004501 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
4502 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004503 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004504 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004505 } else {
4506 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07004507 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004508 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004509 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
4510 mNetworkPacketActivityCounters
4511 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004512 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004513 mNetworkByteActivityCounters[i]
4514 = new LongSamplingCounter(mOnBatteryTimeBase, in);
4515 mNetworkPacketActivityCounters[i]
4516 = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004517 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004518 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
4519 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004520 } else {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004521 mNetworkByteActivityCounters = null;
4522 mNetworkPacketActivityCounters = null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004523 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004524 }
4525
4526 /**
4527 * The statistics associated with a particular wake lock.
4528 */
4529 public final class Wakelock extends BatteryStats.Uid.Wakelock {
4530 /**
4531 * How long (in ms) this uid has been keeping the device partially awake.
4532 */
Evan Millarc64edde2009-04-18 12:26:32 -07004533 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004534
4535 /**
4536 * How long (in ms) this uid has been keeping the device fully awake.
4537 */
Evan Millarc64edde2009-04-18 12:26:32 -07004538 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004539
4540 /**
4541 * How long (in ms) this uid has had a window keeping the device awake.
4542 */
Evan Millarc64edde2009-04-18 12:26:32 -07004543 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004544
4545 /**
4546 * Reads a possibly null Timer from a Parcel. The timer is associated with the
4547 * proper timer pool from the given BatteryStatsImpl object.
4548 *
4549 * @param in the Parcel to be read from.
4550 * return a new Timer, or null.
4551 */
Evan Millarc64edde2009-04-18 12:26:32 -07004552 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004553 TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004554 if (in.readInt() == 0) {
4555 return null;
4556 }
4557
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004558 return new StopwatchTimer(Uid.this, type, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 }
4560
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004561 boolean reset() {
4562 boolean wlactive = false;
4563 if (mTimerFull != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004564 wlactive |= !mTimerFull.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004565 }
4566 if (mTimerPartial != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004567 wlactive |= !mTimerPartial.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004568 }
4569 if (mTimerWindow != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004570 wlactive |= !mTimerWindow.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004571 }
4572 if (!wlactive) {
4573 if (mTimerFull != null) {
4574 mTimerFull.detach();
4575 mTimerFull = null;
4576 }
4577 if (mTimerPartial != null) {
4578 mTimerPartial.detach();
4579 mTimerPartial = null;
4580 }
4581 if (mTimerWindow != null) {
4582 mTimerWindow.detach();
4583 mTimerWindow = null;
4584 }
4585 }
4586 return !wlactive;
4587 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004588
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004589 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004590 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004591 mPartialTimers, screenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004593 mFullTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004594 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004595 mWindowTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004596 }
4597
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004598 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
4599 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
4600 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
4601 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004602 }
4603
4604 @Override
4605 public Timer getWakeTime(int type) {
4606 switch (type) {
4607 case WAKE_TYPE_FULL: return mTimerFull;
4608 case WAKE_TYPE_PARTIAL: return mTimerPartial;
4609 case WAKE_TYPE_WINDOW: return mTimerWindow;
4610 default: throw new IllegalArgumentException("type = " + type);
4611 }
4612 }
4613 }
4614
4615 public final class Sensor extends BatteryStats.Uid.Sensor {
4616 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07004617 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004619 public Sensor(int handle) {
4620 mHandle = handle;
4621 }
4622
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004623 private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004624 if (in.readInt() == 0) {
4625 return null;
4626 }
4627
Evan Millarc64edde2009-04-18 12:26:32 -07004628 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07004630 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004631 mSensorTimers.put(mHandle, pool);
4632 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004633 return new StopwatchTimer(Uid.this, 0, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 }
4635
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004636 boolean reset() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004637 if (mTimer.reset(true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004638 mTimer = null;
4639 return true;
4640 }
4641 return false;
4642 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004643
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004644 void readFromParcelLocked(TimeBase timeBase, Parcel in) {
4645 mTimer = readTimerFromParcel(timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004646 }
4647
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004648 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
4649 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 }
4651
4652 @Override
4653 public Timer getSensorTime() {
4654 return mTimer;
4655 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004656
4657 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 public int getHandle() {
4659 return mHandle;
4660 }
4661 }
4662
4663 /**
4664 * The statistics associated with a particular process.
4665 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004666 public final class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -08004668 * Remains true until removed from the stats.
4669 */
4670 boolean mActive = true;
4671
4672 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004673 * Total time (in 1/100 sec) spent executing in user code.
4674 */
4675 long mUserTime;
4676
4677 /**
4678 * Total time (in 1/100 sec) spent executing in kernel code.
4679 */
4680 long mSystemTime;
4681
4682 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004683 * Amount of time the process was running in the foreground.
4684 */
4685 long mForegroundTime;
4686
4687 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004688 * Number of times the process has been started.
4689 */
4690 int mStarts;
4691
4692 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004693 * The amount of user time loaded from a previous save.
4694 */
4695 long mLoadedUserTime;
4696
4697 /**
4698 * The amount of system time loaded from a previous save.
4699 */
4700 long mLoadedSystemTime;
4701
4702 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004703 * The amount of foreground time loaded from a previous save.
4704 */
4705 long mLoadedForegroundTime;
4706
4707 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004708 * The number of times the process has started from a previous save.
4709 */
4710 int mLoadedStarts;
4711
4712 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004713 * The amount of user time loaded from the previous run.
4714 */
4715 long mLastUserTime;
4716
4717 /**
4718 * The amount of system time loaded from the previous run.
4719 */
4720 long mLastSystemTime;
4721
4722 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004723 * The amount of foreground time loaded from the previous run
4724 */
4725 long mLastForegroundTime;
4726
4727 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004728 * The number of times the process has started from the previous run.
4729 */
4730 int mLastStarts;
4731
4732 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004733 * The amount of user time when last unplugged.
4734 */
4735 long mUnpluggedUserTime;
4736
4737 /**
4738 * The amount of system time when last unplugged.
4739 */
4740 long mUnpluggedSystemTime;
4741
4742 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004743 * The amount of foreground time since unplugged.
4744 */
4745 long mUnpluggedForegroundTime;
4746
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004747 /**
4748 * The number of times the process has started before unplugged.
4749 */
4750 int mUnpluggedStarts;
4751
Amith Yamasanie43530a2009-08-21 13:11:37 -07004752 SamplingCounter[] mSpeedBins;
4753
Dianne Hackborn287952c2010-09-22 22:34:31 -07004754 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004756 Proc() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004757 mOnBatteryTimeBase.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07004758 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004759 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004760
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004761 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 mUnpluggedUserTime = mUserTime;
4763 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004764 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004765 mUnpluggedStarts = mStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004766 }
4767
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004768 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004769 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004770
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004771 void detach() {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004772 mActive = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004773 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004774 for (int i = 0; i < mSpeedBins.length; i++) {
4775 SamplingCounter c = mSpeedBins[i];
4776 if (c != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004777 mOnBatteryTimeBase.remove(c);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004778 mSpeedBins[i] = null;
4779 }
4780 }
4781 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004782
Dianne Hackborn287952c2010-09-22 22:34:31 -07004783 public int countExcessivePowers() {
4784 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004785 }
4786
Dianne Hackborn287952c2010-09-22 22:34:31 -07004787 public ExcessivePower getExcessivePower(int i) {
4788 if (mExcessivePower != null) {
4789 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004790 }
4791 return null;
4792 }
4793
4794 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004795 if (mExcessivePower == null) {
4796 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004797 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07004798 ExcessivePower ew = new ExcessivePower();
4799 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004800 ew.overTime = overTime;
4801 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07004802 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004803 }
4804
Dianne Hackborn287952c2010-09-22 22:34:31 -07004805 public void addExcessiveCpu(long overTime, long usedTime) {
4806 if (mExcessivePower == null) {
4807 mExcessivePower = new ArrayList<ExcessivePower>();
4808 }
4809 ExcessivePower ew = new ExcessivePower();
4810 ew.type = ExcessivePower.TYPE_CPU;
4811 ew.overTime = overTime;
4812 ew.usedTime = usedTime;
4813 mExcessivePower.add(ew);
4814 }
4815
4816 void writeExcessivePowerToParcelLocked(Parcel out) {
4817 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004818 out.writeInt(0);
4819 return;
4820 }
4821
Dianne Hackborn287952c2010-09-22 22:34:31 -07004822 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004823 out.writeInt(N);
4824 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004825 ExcessivePower ew = mExcessivePower.get(i);
4826 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004827 out.writeLong(ew.overTime);
4828 out.writeLong(ew.usedTime);
4829 }
4830 }
4831
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004832 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004833 final int N = in.readInt();
4834 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004835 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004836 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004837 }
4838
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004839 if (N > 10000) {
4840 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
4841 return false;
4842 }
4843
Dianne Hackborn287952c2010-09-22 22:34:31 -07004844 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004845 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07004846 ExcessivePower ew = new ExcessivePower();
4847 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004848 ew.overTime = in.readLong();
4849 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07004850 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004851 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004852 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004853 }
4854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004855 void writeToParcelLocked(Parcel out) {
4856 out.writeLong(mUserTime);
4857 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004858 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004859 out.writeInt(mStarts);
4860 out.writeLong(mLoadedUserTime);
4861 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004862 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004863 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004864 out.writeLong(mUnpluggedUserTime);
4865 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004866 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07004868
4869 out.writeInt(mSpeedBins.length);
4870 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004871 SamplingCounter c = mSpeedBins[i];
4872 if (c != null) {
4873 out.writeInt(1);
4874 c.writeToParcel(out);
4875 } else {
4876 out.writeInt(0);
4877 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004878 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004879
Dianne Hackborn287952c2010-09-22 22:34:31 -07004880 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004881 }
4882
4883 void readFromParcelLocked(Parcel in) {
4884 mUserTime = in.readLong();
4885 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004886 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004887 mStarts = in.readInt();
4888 mLoadedUserTime = in.readLong();
4889 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004890 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004891 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004892 mLastUserTime = 0;
4893 mLastSystemTime = 0;
4894 mLastForegroundTime = 0;
4895 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004896 mUnpluggedUserTime = in.readLong();
4897 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004898 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004899 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07004900
4901 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004902 int steps = getCpuSpeedSteps();
4903 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07004904 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004905 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004906 mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004907 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004908 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004909
Dianne Hackborn287952c2010-09-22 22:34:31 -07004910 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004911 }
4912
4913 public BatteryStatsImpl getBatteryStats() {
4914 return BatteryStatsImpl.this;
4915 }
4916
4917 public void addCpuTimeLocked(int utime, int stime) {
4918 mUserTime += utime;
4919 mSystemTime += stime;
4920 }
4921
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004922 public void addForegroundTimeLocked(long ttime) {
4923 mForegroundTime += ttime;
4924 }
4925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004926 public void incStartsLocked() {
4927 mStarts++;
4928 }
4929
4930 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08004931 public boolean isActive() {
4932 return mActive;
4933 }
4934
4935 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004936 public long getUserTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07004937 long val = mUserTime;
4938 if (which == STATS_CURRENT) {
4939 val -= mLoadedUserTime;
4940 } else if (which == STATS_SINCE_UNPLUGGED) {
4941 val -= mUnpluggedUserTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004942 }
4943 return val;
4944 }
4945
4946 @Override
4947 public long getSystemTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07004948 long val = mSystemTime;
4949 if (which == STATS_CURRENT) {
4950 val -= mLoadedSystemTime;
4951 } else if (which == STATS_SINCE_UNPLUGGED) {
4952 val -= mUnpluggedSystemTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004953 }
4954 return val;
4955 }
4956
4957 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004958 public long getForegroundTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07004959 long val = mForegroundTime;
4960 if (which == STATS_CURRENT) {
4961 val -= mLoadedForegroundTime;
4962 } else if (which == STATS_SINCE_UNPLUGGED) {
4963 val -= mUnpluggedForegroundTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004964 }
4965 return val;
4966 }
4967
4968 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07004970 int val = mStarts;
4971 if (which == STATS_CURRENT) {
4972 val -= mLoadedStarts;
4973 } else if (which == STATS_SINCE_UNPLUGGED) {
4974 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004975 }
4976 return val;
4977 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004978
4979 /* Called by ActivityManagerService when CPU times are updated. */
4980 public void addSpeedStepTimes(long[] values) {
4981 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004982 long amt = values[i];
4983 if (amt != 0) {
4984 SamplingCounter c = mSpeedBins[i];
4985 if (c == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004986 mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004987 }
4988 c.addCountAtomic(values[i]);
4989 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004990 }
4991 }
4992
4993 @Override
4994 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
4995 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004996 SamplingCounter c = mSpeedBins[speedStep];
4997 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07004998 } else {
4999 return 0;
5000 }
5001 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 }
5003
5004 /**
5005 * The statistics associated with a particular package.
5006 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005007 public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005008 /**
5009 * Number of times this package has done something that could wake up the
5010 * device from sleep.
5011 */
5012 int mWakeups;
5013
5014 /**
5015 * Number of things that could wake up the device loaded from a
5016 * previous save.
5017 */
5018 int mLoadedWakeups;
5019
5020 /**
5021 * Number of things that could wake up the device as of the
5022 * last run.
5023 */
5024 int mLastWakeups;
5025
5026 /**
5027 * Number of things that could wake up the device as of the
5028 * last run.
5029 */
5030 int mUnpluggedWakeups;
5031
5032 /**
5033 * The statics we have collected for this package's services.
5034 */
5035 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
5036
5037 Pkg() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005038 mOnBatteryScreenOffTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005039 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005040
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005041 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005042 mUnpluggedWakeups = mWakeups;
5043 }
5044
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005045 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005046 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005047
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005048 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005049 mOnBatteryScreenOffTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005050 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052 void readFromParcelLocked(Parcel in) {
5053 mWakeups = in.readInt();
5054 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005055 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005056 mUnpluggedWakeups = in.readInt();
5057
5058 int numServs = in.readInt();
5059 mServiceStats.clear();
5060 for (int m = 0; m < numServs; m++) {
5061 String serviceName = in.readString();
5062 Uid.Pkg.Serv serv = new Serv();
5063 mServiceStats.put(serviceName, serv);
5064
5065 serv.readFromParcelLocked(in);
5066 }
5067 }
5068
5069 void writeToParcelLocked(Parcel out) {
5070 out.writeInt(mWakeups);
5071 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005072 out.writeInt(mUnpluggedWakeups);
5073
5074 out.writeInt(mServiceStats.size());
5075 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
5076 out.writeString(servEntry.getKey());
5077 Uid.Pkg.Serv serv = servEntry.getValue();
5078
5079 serv.writeToParcelLocked(out);
5080 }
5081 }
5082
5083 @Override
5084 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
5085 return mServiceStats;
5086 }
5087
5088 @Override
5089 public int getWakeups(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07005090 int val = mWakeups;
5091 if (which == STATS_CURRENT) {
5092 val -= mLoadedWakeups;
5093 } else if (which == STATS_SINCE_UNPLUGGED) {
5094 val -= mUnpluggedWakeups;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005095 }
5096
5097 return val;
5098 }
5099
5100 /**
5101 * The statistics associated with a particular service.
5102 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005103 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005104 /**
5105 * Total time (ms in battery uptime) the service has been left started.
5106 */
5107 long mStartTime;
5108
5109 /**
5110 * If service has been started and not yet stopped, this is
5111 * when it was started.
5112 */
5113 long mRunningSince;
5114
5115 /**
5116 * True if we are currently running.
5117 */
5118 boolean mRunning;
5119
5120 /**
5121 * Total number of times startService() has been called.
5122 */
5123 int mStarts;
5124
5125 /**
5126 * Total time (ms in battery uptime) the service has been left launched.
5127 */
5128 long mLaunchedTime;
5129
5130 /**
5131 * If service has been launched and not yet exited, this is
5132 * when it was launched (ms in battery uptime).
5133 */
5134 long mLaunchedSince;
5135
5136 /**
5137 * True if we are currently launched.
5138 */
5139 boolean mLaunched;
5140
5141 /**
5142 * Total number times the service has been launched.
5143 */
5144 int mLaunches;
5145
5146 /**
5147 * The amount of time spent started loaded from a previous save
5148 * (ms in battery uptime).
5149 */
5150 long mLoadedStartTime;
5151
5152 /**
5153 * The number of starts loaded from a previous save.
5154 */
5155 int mLoadedStarts;
5156
5157 /**
5158 * The number of launches loaded from a previous save.
5159 */
5160 int mLoadedLaunches;
5161
5162 /**
5163 * The amount of time spent started as of the last run (ms
5164 * in battery uptime).
5165 */
5166 long mLastStartTime;
5167
5168 /**
5169 * The number of starts as of the last run.
5170 */
5171 int mLastStarts;
5172
5173 /**
5174 * The number of launches as of the last run.
5175 */
5176 int mLastLaunches;
5177
5178 /**
5179 * The amount of time spent started when last unplugged (ms
5180 * in battery uptime).
5181 */
5182 long mUnpluggedStartTime;
5183
5184 /**
5185 * The number of starts when last unplugged.
5186 */
5187 int mUnpluggedStarts;
5188
5189 /**
5190 * The number of launches when last unplugged.
5191 */
5192 int mUnpluggedLaunches;
5193
5194 Serv() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005195 mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005196 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005197
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005198 public void onTimeStarted(long elapsedRealtime, long baseUptime,
5199 long baseRealtime) {
5200 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005201 mUnpluggedStarts = mStarts;
5202 mUnpluggedLaunches = mLaunches;
5203 }
5204
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005205 public void onTimeStopped(long elapsedRealtime, long baseUptime,
5206 long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005208
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005209 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005210 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005211 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 void readFromParcelLocked(Parcel in) {
5214 mStartTime = in.readLong();
5215 mRunningSince = in.readLong();
5216 mRunning = in.readInt() != 0;
5217 mStarts = in.readInt();
5218 mLaunchedTime = in.readLong();
5219 mLaunchedSince = in.readLong();
5220 mLaunched = in.readInt() != 0;
5221 mLaunches = in.readInt();
5222 mLoadedStartTime = in.readLong();
5223 mLoadedStarts = in.readInt();
5224 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005225 mLastStartTime = 0;
5226 mLastStarts = 0;
5227 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005228 mUnpluggedStartTime = in.readLong();
5229 mUnpluggedStarts = in.readInt();
5230 mUnpluggedLaunches = in.readInt();
5231 }
5232
5233 void writeToParcelLocked(Parcel out) {
5234 out.writeLong(mStartTime);
5235 out.writeLong(mRunningSince);
5236 out.writeInt(mRunning ? 1 : 0);
5237 out.writeInt(mStarts);
5238 out.writeLong(mLaunchedTime);
5239 out.writeLong(mLaunchedSince);
5240 out.writeInt(mLaunched ? 1 : 0);
5241 out.writeInt(mLaunches);
5242 out.writeLong(mLoadedStartTime);
5243 out.writeInt(mLoadedStarts);
5244 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005245 out.writeLong(mUnpluggedStartTime);
5246 out.writeInt(mUnpluggedStarts);
5247 out.writeInt(mUnpluggedLaunches);
5248 }
5249
5250 long getLaunchTimeToNowLocked(long batteryUptime) {
5251 if (!mLaunched) return mLaunchedTime;
5252 return mLaunchedTime + batteryUptime - mLaunchedSince;
5253 }
5254
5255 long getStartTimeToNowLocked(long batteryUptime) {
5256 if (!mRunning) return mStartTime;
5257 return mStartTime + batteryUptime - mRunningSince;
5258 }
5259
5260 public void startLaunchedLocked() {
5261 if (!mLaunched) {
5262 mLaunches++;
5263 mLaunchedSince = getBatteryUptimeLocked();
5264 mLaunched = true;
5265 }
5266 }
5267
5268 public void stopLaunchedLocked() {
5269 if (mLaunched) {
5270 long time = getBatteryUptimeLocked() - mLaunchedSince;
5271 if (time > 0) {
5272 mLaunchedTime += time;
5273 } else {
5274 mLaunches--;
5275 }
5276 mLaunched = false;
5277 }
5278 }
5279
5280 public void startRunningLocked() {
5281 if (!mRunning) {
5282 mStarts++;
5283 mRunningSince = getBatteryUptimeLocked();
5284 mRunning = true;
5285 }
5286 }
5287
5288 public void stopRunningLocked() {
5289 if (mRunning) {
5290 long time = getBatteryUptimeLocked() - mRunningSince;
5291 if (time > 0) {
5292 mStartTime += time;
5293 } else {
5294 mStarts--;
5295 }
5296 mRunning = false;
5297 }
5298 }
5299
5300 public BatteryStatsImpl getBatteryStats() {
5301 return BatteryStatsImpl.this;
5302 }
5303
5304 @Override
5305 public int getLaunches(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07005306 int val = mLaunches;
5307 if (which == STATS_CURRENT) {
5308 val -= mLoadedLaunches;
5309 } else if (which == STATS_SINCE_UNPLUGGED) {
5310 val -= mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005312 return val;
5313 }
5314
5315 @Override
5316 public long getStartTime(long now, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07005317 long val = getStartTimeToNowLocked(now);
5318 if (which == STATS_CURRENT) {
5319 val -= mLoadedStartTime;
5320 } else if (which == STATS_SINCE_UNPLUGGED) {
5321 val -= mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005323 return val;
5324 }
5325
5326 @Override
5327 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07005328 int val = mStarts;
5329 if (which == STATS_CURRENT) {
5330 val -= mLoadedStarts;
5331 } else if (which == STATS_SINCE_UNPLUGGED) {
5332 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005333 }
5334
5335 return val;
5336 }
5337 }
5338
5339 public BatteryStatsImpl getBatteryStats() {
5340 return BatteryStatsImpl.this;
5341 }
5342
5343 public void incWakeupsLocked() {
5344 mWakeups++;
5345 }
5346
5347 final Serv newServiceStatsLocked() {
5348 return new Serv();
5349 }
5350 }
5351
5352 /**
5353 * Retrieve the statistics object for a particular process, creating
5354 * if needed.
5355 */
5356 public Proc getProcessStatsLocked(String name) {
5357 Proc ps = mProcessStats.get(name);
5358 if (ps == null) {
5359 ps = new Proc();
5360 mProcessStats.put(name, ps);
5361 }
5362
5363 return ps;
5364 }
5365
Dianne Hackbornb5e31652010-09-07 12:13:55 -07005366 public SparseArray<? extends Pid> getPidStats() {
5367 return mPids;
5368 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005369
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005370 public Pid getPidStatsLocked(int pid) {
5371 Pid p = mPids.get(pid);
5372 if (p == null) {
5373 p = new Pid();
5374 mPids.put(pid, p);
5375 }
5376 return p;
5377 }
5378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005379 /**
5380 * Retrieve the statistics object for a particular service, creating
5381 * if needed.
5382 */
5383 public Pkg getPackageStatsLocked(String name) {
5384 Pkg ps = mPackageStats.get(name);
5385 if (ps == null) {
5386 ps = new Pkg();
5387 mPackageStats.put(name, ps);
5388 }
5389
5390 return ps;
5391 }
5392
5393 /**
5394 * Retrieve the statistics object for a particular service, creating
5395 * if needed.
5396 */
5397 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
5398 Pkg ps = getPackageStatsLocked(pkg);
5399 Pkg.Serv ss = ps.mServiceStats.get(serv);
5400 if (ss == null) {
5401 ss = ps.newServiceStatsLocked();
5402 ps.mServiceStats.put(serv, ss);
5403 }
5404
5405 return ss;
5406 }
5407
Evan Millarc64edde2009-04-18 12:26:32 -07005408 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005409 Wakelock wl = mWakelockStats.get(name);
5410 if (wl == null) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07005411 final int N = mWakelockStats.size();
Dianne Hackbornaf17baa2013-05-09 15:27:47 -07005412 if (N > MAX_WAKELOCKS_PER_UID) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005413 name = BATCHED_WAKELOCK_NAME;
5414 wl = mWakelockStats.get(name);
5415 }
5416 if (wl == null) {
5417 wl = new Wakelock();
5418 mWakelockStats.put(name, wl);
5419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005420 }
Evan Millarc64edde2009-04-18 12:26:32 -07005421 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005422 switch (type) {
5423 case WAKE_TYPE_PARTIAL:
5424 t = wl.mTimerPartial;
5425 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005426 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005427 mPartialTimers, mOnBatteryScreenOffTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005428 wl.mTimerPartial = t;
5429 }
5430 return t;
5431 case WAKE_TYPE_FULL:
5432 t = wl.mTimerFull;
5433 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005434 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005435 mFullTimers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 wl.mTimerFull = t;
5437 }
5438 return t;
5439 case WAKE_TYPE_WINDOW:
5440 t = wl.mTimerWindow;
5441 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005442 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005443 mWindowTimers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005444 wl.mTimerWindow = t;
5445 }
5446 return t;
5447 default:
5448 throw new IllegalArgumentException("type=" + type);
5449 }
5450 }
5451
Evan Millarc64edde2009-04-18 12:26:32 -07005452 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005453 Sensor se = mSensorStats.get(sensor);
5454 if (se == null) {
5455 if (!create) {
5456 return null;
5457 }
5458 se = new Sensor(sensor);
5459 mSensorStats.put(sensor, se);
5460 }
Evan Millarc64edde2009-04-18 12:26:32 -07005461 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005462 if (t != null) {
5463 return t;
5464 }
Evan Millarc64edde2009-04-18 12:26:32 -07005465 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07005467 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005468 mSensorTimers.put(sensor, timers);
5469 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005470 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005471 se.mTimer = t;
5472 return t;
5473 }
5474
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005475 public void noteStartWakeLocked(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.startRunningLocked(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 = getPidStatsLocked(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005482 if (p.mWakeNesting++ == 0) {
5483 p.mWakeStartMs = elapsedRealtimeMs;
Dianne Hackbornb8071d792010-09-09 16:45:15 -07005484 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005486 }
5487
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005488 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005489 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005490 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005491 t.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005492 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07005493 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005494 Pid p = mPids.get(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005495 if (p != null && p.mWakeNesting > 0) {
5496 if (p.mWakeNesting-- == 1) {
5497 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
5498 p.mWakeStartMs = 0;
5499 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005500 }
5501 }
5502 }
5503
5504 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
5505 Proc p = getProcessStatsLocked(proc);
5506 if (p != null) {
5507 p.addExcessiveWake(overTime, usedTime);
5508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005509 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005510
Dianne Hackborn287952c2010-09-22 22:34:31 -07005511 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
5512 Proc p = getProcessStatsLocked(proc);
5513 if (p != null) {
5514 p.addExcessiveCpu(overTime, usedTime);
5515 }
5516 }
5517
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005518 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005519 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005520 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005521 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005523 }
5524
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005525 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005526 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07005527 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005528 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005529 t.stopRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005532
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005533 public void noteStartGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005534 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005535 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005536 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005538 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005539
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005540 public void noteStopGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07005541 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005542 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005543 t.stopRunningLocked(elapsedRealtimeMs);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005545 }
5546
5547 public BatteryStatsImpl getBatteryStats() {
5548 return BatteryStatsImpl.this;
5549 }
5550 }
5551
Jeff Brown6f357d32014-01-15 20:40:55 -08005552 public BatteryStatsImpl(String filename, Handler handler) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005553 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Jeff Brown6f357d32014-01-15 20:40:55 -08005554 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005555 mStartCount++;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005556 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005557 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005558 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005559 }
Dianne Hackborn29325132014-05-21 15:01:03 -07005560 mInteractiveTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005561 mLowPowerModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase);
5562 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase);
Wink Saville52840902011-02-18 12:40:47 -08005563 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005564 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null,
5565 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005566 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005567 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005568 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005569 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null,
5570 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005571 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005572 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005573 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
5574 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005575 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005576 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase);
5577 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005578 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005579 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
5580 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005581 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase);
5582 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005583 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005584 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005585 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005586 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005587 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005588 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, null, mOnBatteryTimeBase);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08005589 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005590 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
5591 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005592 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005593 long uptime = SystemClock.uptimeMillis() * 1000;
5594 long realtime = SystemClock.elapsedRealtime() * 1000;
5595 initTimes(uptime, realtime);
Evan Millar633a1742009-04-02 16:36:33 -07005596 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005597 mDischargeUnplugLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07005598 mDischargePlugLevel = -1;
Evan Millar633a1742009-04-02 16:36:33 -07005599 mDischargeCurrentLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07005600 mCurrentBatteryLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005601 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005602 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005603 }
5604
5605 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005606 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005607 mHandler = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005608 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005609 readFromParcel(p);
5610 }
5611
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005612 public void setCallback(BatteryCallback cb) {
5613 mCallback = cb;
5614 }
5615
Amith Yamasanie43530a2009-08-21 13:11:37 -07005616 public void setNumSpeedSteps(int steps) {
5617 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
5618 }
5619
Amith Yamasanif37447b2009-10-08 18:28:01 -07005620 public void setRadioScanningTimeout(long timeout) {
5621 if (mPhoneSignalScanningTimer != null) {
5622 mPhoneSignalScanningTimer.setTimeout(timeout);
5623 }
5624 }
5625
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005626 @Override
5627 public boolean startIteratingOldHistoryLocked() {
5628 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
5629 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005630 if ((mHistoryIterator = mHistory) == null) {
5631 return false;
5632 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005633 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005634 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005635 mReadOverflow = false;
5636 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005637 return true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005638 }
5639
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005640 @Override
5641 public boolean getNextOldHistoryLocked(HistoryItem out) {
5642 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
5643 if (!end) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005644 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005645 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005646 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005647 HistoryItem cur = mHistoryIterator;
5648 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005649 if (!mReadOverflow && !end) {
5650 Slog.w(TAG, "Old history ends before new history!");
5651 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005652 return false;
5653 }
5654 out.setTo(cur);
5655 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005656 if (!mReadOverflow) {
5657 if (end) {
5658 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005659 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn8c841092013-06-24 13:46:13 -07005660 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005661 pw.println("Histories differ!");
5662 pw.println("Old history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07005663 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005664 pw.println("New history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07005665 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false,
5666 true);
Dianne Hackborn8c841092013-06-24 13:46:13 -07005667 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005668 }
5669 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005670 return true;
5671 }
5672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005673 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005674 public void finishIteratingOldHistoryLocked() {
5675 mIteratingHistory = false;
5676 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005677 mHistoryIterator = null;
5678 }
5679
5680 public int getHistoryTotalSize() {
5681 return MAX_HISTORY_BUFFER;
5682 }
5683
5684 public int getHistoryUsedSize() {
5685 return mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005686 }
5687
5688 @Override
5689 public boolean startIteratingHistoryLocked() {
5690 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
5691 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005692 if (mHistoryBuffer.dataSize() <= 0) {
5693 return false;
5694 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005695 mHistoryBuffer.setDataPosition(0);
5696 mReadOverflow = false;
5697 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005698 mReadHistoryStrings = new String[mHistoryTagPool.size()];
5699 mReadHistoryUids = new int[mHistoryTagPool.size()];
5700 mReadHistoryChars = 0;
5701 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
5702 final HistoryTag tag = ent.getKey();
5703 final int idx = ent.getValue();
5704 mReadHistoryStrings[idx] = tag.string;
5705 mReadHistoryUids[idx] = tag.uid;
5706 mReadHistoryChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08005707 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005708 return true;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005709 }
5710
5711 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08005712 public int getHistoryStringPoolSize() {
5713 return mReadHistoryStrings.length;
5714 }
5715
5716 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005717 public int getHistoryStringPoolBytes() {
5718 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
5719 // Each string character is 2 bytes.
5720 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
5721 }
5722
5723 @Override
5724 public String getHistoryTagPoolString(int index) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005725 return mReadHistoryStrings[index];
5726 }
5727
5728 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08005729 public int getHistoryTagPoolUid(int index) {
5730 return mReadHistoryUids[index];
5731 }
5732
5733 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005734 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07005735 final int pos = mHistoryBuffer.dataPosition();
5736 if (pos == 0) {
5737 out.clear();
5738 }
5739 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005740 if (end) {
5741 return false;
5742 }
5743
Dianne Hackborn99009ea2014-04-18 16:23:42 -07005744 final long lastRealtime = out.time;
5745 final long lastWalltime = out.currentTime;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005746 readHistoryDelta(mHistoryBuffer, out);
Dianne Hackborn37de0982014-05-09 09:32:18 -07005747 if (out.cmd != HistoryItem.CMD_CURRENT_TIME
5748 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
Dianne Hackborn99009ea2014-04-18 16:23:42 -07005749 out.currentTime = lastWalltime + (out.time - lastRealtime);
5750 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005751 return true;
5752 }
5753
5754 @Override
5755 public void finishIteratingHistoryLocked() {
5756 mIteratingHistory = false;
5757 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn099bc622014-01-22 13:39:16 -08005758 mReadHistoryStrings = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005759 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005760
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005761 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07005762 public long getHistoryBaseTime() {
5763 return mHistoryBaseTime;
5764 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005765
Dianne Hackbornb5e31652010-09-07 12:13:55 -07005766 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005767 public int getStartCount() {
5768 return mStartCount;
5769 }
5770
5771 public boolean isOnBattery() {
5772 return mOnBattery;
5773 }
5774
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005775 public boolean isScreenOn() {
Jeff Browne95c3cd2014-05-02 16:59:26 -07005776 return mScreenState == Display.STATE_ON;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005777 }
5778
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005779 void initTimes(long uptime, long realtime) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08005780 mStartClockTime = System.currentTimeMillis();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005781 mOnBatteryTimeBase.init(uptime, realtime);
5782 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
Dianne Hackborn4590e522014-03-24 13:36:46 -07005783 mRealtime = 0;
5784 mUptime = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005785 mRealtimeStart = realtime;
Dianne Hackborn4590e522014-03-24 13:36:46 -07005786 mUptimeStart = uptime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005787 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005788
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005789 void initDischarge() {
5790 mLowDischargeAmountSinceCharge = 0;
5791 mHighDischargeAmountSinceCharge = 0;
5792 mDischargeAmountScreenOn = 0;
5793 mDischargeAmountScreenOnSinceCharge = 0;
5794 mDischargeAmountScreenOff = 0;
5795 mDischargeAmountScreenOffSinceCharge = 0;
Dianne Hackborn260c5022014-04-29 11:23:16 -07005796 mLastDischargeStepTime = -1;
5797 mNumDischargeStepDurations = 0;
5798 mLastChargeStepTime = -1;
5799 mNumChargeStepDurations = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005800 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005801
5802 public void resetAllStatsCmdLocked() {
5803 resetAllStatsLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07005804 final long mSecUptime = SystemClock.uptimeMillis();
5805 long uptime = mSecUptime * 1000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005806 long mSecRealtime = SystemClock.elapsedRealtime();
5807 long realtime = mSecRealtime * 1000;
5808 mDischargeStartLevel = mHistoryCur.batteryLevel;
5809 pullPendingStateUpdatesLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07005810 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07005811 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
5812 = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005813 mOnBatteryTimeBase.reset(uptime, realtime);
5814 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
5815 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07005816 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005817 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
5818 mDischargeScreenOffUnplugLevel = 0;
5819 } else {
5820 mDischargeScreenOnUnplugLevel = 0;
5821 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
5822 }
5823 mDischargeAmountScreenOn = 0;
5824 mDischargeAmountScreenOff = 0;
5825 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07005826 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08005827 }
5828
5829 private void resetAllStatsLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005830 mStartCount = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005831 initTimes(SystemClock.uptimeMillis() * 1000, SystemClock.elapsedRealtime() * 1000);
5832 mScreenOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005833 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005834 mScreenBrightnessTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005835 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07005836 mInteractiveTimer.reset(false);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005837 mLowPowerModeEnabledTimer.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005838 mPhoneOnTimer.reset(false);
5839 mAudioOnTimer.reset(false);
5840 mVideoOnTimer.reset(false);
Wink Saville52840902011-02-18 12:40:47 -08005841 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005842 mPhoneSignalStrengthsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005843 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005844 mPhoneSignalScanningTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005845 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005846 mPhoneDataConnectionsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005847 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005848 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005849 mNetworkByteActivityCounters[i].reset(false);
5850 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005851 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005852 mMobileRadioActiveTimer.reset(false);
5853 mMobileRadioActivePerAppTimer.reset(false);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005854 mMobileRadioActiveAdjustedTime.reset(false);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005855 mMobileRadioActiveUnknownTime.reset(false);
5856 mMobileRadioActiveUnknownCount.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005857 mWifiOnTimer.reset(false);
5858 mGlobalWifiRunningTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005859 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005860 mWifiStateTimer[i].reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005861 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005862 mBluetoothOnTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005863 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005864 mBluetoothStateTimer[i].reset(false);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08005865 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005866
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005867 for (int i=0; i<mUidStats.size(); i++) {
5868 if (mUidStats.valueAt(i).reset()) {
5869 mUidStats.remove(mUidStats.keyAt(i));
5870 i--;
5871 }
5872 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005873
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005874 if (mKernelWakelockStats.size() > 0) {
5875 for (SamplingTimer timer : mKernelWakelockStats.values()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005876 mOnBatteryScreenOffTimeBase.remove(timer);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005877 }
5878 mKernelWakelockStats.clear();
5879 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005880
5881 if (mWakeupReasonStats.size() > 0) {
5882 for (LongSamplingCounter timer : mWakeupReasonStats.values()) {
5883 mOnBatteryScreenOffTimeBase.remove(timer);
5884 }
5885 mWakeupReasonStats.clear();
5886 }
5887
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005888 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005889
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005890 clearHistoryLocked();
5891 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005892
Dianne Hackborn40c87252014-03-19 16:55:40 -07005893 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005894 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07005895 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005896 if (active == null) {
5897 continue;
5898 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07005899 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
5900 SparseIntArray uids = ent.getValue();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005901 for (int j=0; j<uids.size(); j++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07005902 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
5903 uids.keyAt(j));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005904 }
5905 }
5906 }
5907 }
5908
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005909 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005910 if (oldScreenOn) {
5911 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
5912 if (diff > 0) {
5913 mDischargeAmountScreenOn += diff;
5914 mDischargeAmountScreenOnSinceCharge += diff;
5915 }
5916 } else {
5917 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
5918 if (diff > 0) {
5919 mDischargeAmountScreenOff += diff;
5920 mDischargeAmountScreenOffSinceCharge += diff;
5921 }
5922 }
5923 if (newScreenOn) {
5924 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
5925 mDischargeScreenOffUnplugLevel = 0;
5926 } else {
5927 mDischargeScreenOnUnplugLevel = 0;
5928 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
5929 }
5930 }
5931
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005932 public void pullPendingStateUpdatesLocked() {
5933 updateKernelWakelocksLocked();
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005934 updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
Dianne Hackborn77b987f2014-02-26 16:20:52 -08005935 if (mOnBatteryInternal) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07005936 final boolean screenOn = mScreenState == Display.STATE_ON;
5937 updateDischargeScreenLevelsLocked(screenOn, screenOn);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08005938 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005939 }
5940
Dianne Hackborn40c87252014-03-19 16:55:40 -07005941 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
5942 final int oldStatus, final int level) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005943 boolean doWrite = false;
5944 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
5945 m.arg1 = onBattery ? 1 : 0;
5946 mHandler.sendMessage(m);
5947 mOnBattery = mOnBatteryInternal = onBattery;
5948
Dianne Hackborn40c87252014-03-19 16:55:40 -07005949 final long uptime = mSecUptime * 1000;
5950 final long realtime = mSecRealtime * 1000;
Jeff Browne95c3cd2014-05-02 16:59:26 -07005951 final boolean screenOn = mScreenState == Display.STATE_ON;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005952 if (onBattery) {
5953 // We will reset our status if we are unplugging after the
5954 // battery was last full, or the level is at 100, or
5955 // we have gone through a significant charge (from a very low
5956 // level to a now very high level).
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005957 boolean reset = false;
Dianne Hackborn9a755432014-05-15 17:05:22 -07005958 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005959 || level >= 90
Dianne Hackborn9a755432014-05-15 17:05:22 -07005960 || (mDischargeCurrentLevel < 20 && level >= 80))) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005961 doWrite = true;
5962 resetAllStatsLocked();
5963 mDischargeStartLevel = level;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08005964 reset = true;
Dianne Hackborn260c5022014-04-29 11:23:16 -07005965 mNumDischargeStepDurations = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005966 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07005967 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07005968 mMinDischargeStepLevel = level;
Dianne Hackborn260c5022014-04-29 11:23:16 -07005969 mLastDischargeStepTime = -1;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005970 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005971 mHistoryCur.batteryLevel = (byte)level;
5972 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
5973 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
5974 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005975 if (reset) {
5976 mRecordingHistory = true;
5977 startRecordingHistory(mSecRealtime, mSecUptime, reset);
5978 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07005979 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005980 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
Jeff Browne95c3cd2014-05-02 16:59:26 -07005981 if (screenOn) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005982 mDischargeScreenOnUnplugLevel = level;
5983 mDischargeScreenOffUnplugLevel = 0;
5984 } else {
5985 mDischargeScreenOnUnplugLevel = 0;
5986 mDischargeScreenOffUnplugLevel = level;
5987 }
5988 mDischargeAmountScreenOn = 0;
5989 mDischargeAmountScreenOff = 0;
Jeff Browne95c3cd2014-05-02 16:59:26 -07005990 updateTimeBasesLocked(true, !screenOn, uptime, realtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005991 } else {
Dianne Hackborna7c837f2014-01-15 16:20:44 -08005992 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005993 mHistoryCur.batteryLevel = (byte)level;
5994 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
5995 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
5996 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005997 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07005998 mDischargeCurrentLevel = mDischargePlugLevel = level;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08005999 if (level < mDischargeUnplugLevel) {
6000 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
6001 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
6002 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07006003 updateDischargeScreenLevelsLocked(screenOn, screenOn);
6004 updateTimeBasesLocked(false, !screenOn, uptime, realtime);
Dianne Hackborn260c5022014-04-29 11:23:16 -07006005 mNumChargeStepDurations = 0;
6006 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07006007 mMaxChargeStepLevel = level;
Dianne Hackborn260c5022014-04-29 11:23:16 -07006008 mLastChargeStepTime = -1;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006009 }
6010 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
6011 if (mFile != null) {
6012 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006013 }
6014 }
6015 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006016
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006017 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
6018 boolean reset) {
6019 mRecordingHistory = true;
6020 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn37de0982014-05-09 09:32:18 -07006021 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
6022 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006023 mHistoryCur);
6024 mHistoryCur.currentTime = 0;
6025 if (reset) {
6026 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
6027 }
6028 }
6029
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006030 // This should probably be exposed in the API, though it's not critical
6031 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006032
Dianne Hackborn260c5022014-04-29 11:23:16 -07006033 private static int addLevelSteps(long[] steps, int stepCount, long lastStepTime,
6034 int numStepLevels, long elapsedRealtime) {
6035 if (lastStepTime >= 0 && numStepLevels > 0) {
6036 long duration = elapsedRealtime - lastStepTime;
6037 for (int i=0; i<numStepLevels; i++) {
6038 System.arraycopy(steps, 0, steps, 1, steps.length-1);
6039 long thisDuration = duration / (numStepLevels-i);
6040 duration -= thisDuration;
6041 steps[0] = thisDuration;
6042 }
6043 stepCount += numStepLevels;
6044 if (stepCount > steps.length) {
6045 stepCount = steps.length;
6046 }
6047 }
6048 return stepCount;
6049 }
6050
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006051 public void setBatteryState(int status, int health, int plugType, int level,
6052 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006053 synchronized(this) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07006054 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
6055 final long uptime = SystemClock.uptimeMillis();
6056 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006057 int oldStatus = mHistoryCur.batteryStatus;
6058 if (!mHaveBatteryLevel) {
6059 mHaveBatteryLevel = true;
6060 // We start out assuming that the device is plugged in (not
6061 // on battery). If our first report is now that we are indeed
6062 // plugged in, then twiddle our state to correctly reflect that
6063 // since we won't be going through the full setOnBattery().
6064 if (onBattery == mOnBattery) {
6065 if (onBattery) {
6066 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
6067 } else {
6068 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
6069 }
6070 }
6071 oldStatus = status;
6072 }
6073 if (onBattery) {
6074 mDischargeCurrentLevel = level;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006075 if (!mRecordingHistory) {
6076 mRecordingHistory = true;
6077 startRecordingHistory(elapsedRealtime, uptime, true);
6078 }
6079 } else if (level < 96) {
6080 if (!mRecordingHistory) {
6081 mRecordingHistory = true;
6082 startRecordingHistory(elapsedRealtime, uptime, true);
6083 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006084 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006085 mCurrentBatteryLevel = level;
6086 if (mDischargePlugLevel < 0) {
6087 mDischargePlugLevel = level;
6088 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006089 if (onBattery != mOnBattery) {
6090 mHistoryCur.batteryLevel = (byte)level;
6091 mHistoryCur.batteryStatus = (byte)status;
6092 mHistoryCur.batteryHealth = (byte)health;
6093 mHistoryCur.batteryPlugType = (byte)plugType;
Sungmin Choic7e9e8b2013-01-16 12:57:36 +09006094 mHistoryCur.batteryTemperature = (short)temp;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006095 mHistoryCur.batteryVoltage = (char)volt;
Dianne Hackborn40c87252014-03-19 16:55:40 -07006096 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006097 } else {
6098 boolean changed = false;
6099 if (mHistoryCur.batteryLevel != level) {
6100 mHistoryCur.batteryLevel = (byte)level;
6101 changed = true;
6102 }
6103 if (mHistoryCur.batteryStatus != status) {
6104 mHistoryCur.batteryStatus = (byte)status;
6105 changed = true;
6106 }
6107 if (mHistoryCur.batteryHealth != health) {
6108 mHistoryCur.batteryHealth = (byte)health;
6109 changed = true;
6110 }
6111 if (mHistoryCur.batteryPlugType != plugType) {
6112 mHistoryCur.batteryPlugType = (byte)plugType;
6113 changed = true;
6114 }
6115 if (temp >= (mHistoryCur.batteryTemperature+10)
6116 || temp <= (mHistoryCur.batteryTemperature-10)) {
Sungmin Choic7e9e8b2013-01-16 12:57:36 +09006117 mHistoryCur.batteryTemperature = (short)temp;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006118 changed = true;
6119 }
6120 if (volt > (mHistoryCur.batteryVoltage+20)
6121 || volt < (mHistoryCur.batteryVoltage-20)) {
6122 mHistoryCur.batteryVoltage = (char)volt;
6123 changed = true;
6124 }
6125 if (changed) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07006126 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006127 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07006128 if (onBattery) {
Dianne Hackborn29325132014-05-21 15:01:03 -07006129 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07006130 mNumDischargeStepDurations = addLevelSteps(mDischargeStepDurations,
6131 mNumDischargeStepDurations, mLastDischargeStepTime,
6132 mLastDischargeStepLevel - level, elapsedRealtime);
6133 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07006134 mMinDischargeStepLevel = level;
Dianne Hackborn260c5022014-04-29 11:23:16 -07006135 mLastDischargeStepTime = elapsedRealtime;
6136 }
6137 } else {
Dianne Hackborn29325132014-05-21 15:01:03 -07006138 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07006139 mNumChargeStepDurations = addLevelSteps(mChargeStepDurations,
6140 mNumChargeStepDurations, mLastChargeStepTime,
6141 level - mLastChargeStepLevel, elapsedRealtime);
6142 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07006143 mMaxChargeStepLevel = level;
Dianne Hackborn260c5022014-04-29 11:23:16 -07006144 mLastChargeStepTime = elapsedRealtime;
6145 }
6146 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006147 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08006148 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
6149 // We don't record history while we are plugged in and fully charged.
6150 // The next time we are unplugged, history will be cleared.
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08006151 mRecordingHistory = DEBUG;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006152 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006153 }
Evan Millar633a1742009-04-02 16:36:33 -07006154 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006155
Evan Millarc64edde2009-04-18 12:26:32 -07006156 public void updateKernelWakelocksLocked() {
6157 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006158
Marco Nelissend8593312009-04-30 14:45:06 -07006159 if (m == null) {
6160 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006161 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07006162 return;
6163 }
6164
Evan Millarc64edde2009-04-18 12:26:32 -07006165 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
6166 String name = ent.getKey();
6167 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006168
Evan Millarc64edde2009-04-18 12:26:32 -07006169 SamplingTimer kwlt = mKernelWakelockStats.get(name);
6170 if (kwlt == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006171 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
6172 true /* track reported val */);
Evan Millarc64edde2009-04-18 12:26:32 -07006173 mKernelWakelockStats.put(name, kwlt);
6174 }
6175 kwlt.updateCurrentReportedCount(kws.mCount);
6176 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
6177 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
6178 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006179
Evan Millarc64edde2009-04-18 12:26:32 -07006180 if (m.size() != mKernelWakelockStats.size()) {
6181 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
6182 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
6183 SamplingTimer st = ent.getValue();
6184 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
6185 st.setStale();
6186 }
6187 }
6188 }
6189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006190
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006191 static final int NET_UPDATE_MOBILE = 1<<0;
6192 static final int NET_UPDATE_WIFI = 1<<1;
6193 static final int NET_UPDATE_ALL = 0xffff;
6194
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006195 private void updateNetworkActivityLocked(int which, long elapsedRealtimeMs) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006196 if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
6197
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006198 if ((which&NET_UPDATE_MOBILE) != 0 && mMobileIfaces.length > 0) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006199 final NetworkStats snapshot;
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006200 final NetworkStats last = mCurMobileSnapshot;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006201 try {
6202 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
6203 mMobileIfaces, NetworkStats.TAG_NONE, mLastMobileSnapshot);
6204 } catch (IOException e) {
6205 Log.wtf(TAG, "Failed to read mobile network stats", e);
6206 return;
6207 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006208
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006209 mCurMobileSnapshot = snapshot;
6210 mLastMobileSnapshot = last;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006211
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006212 if (mOnBatteryInternal) {
6213 final NetworkStats delta = NetworkStats.subtract(snapshot, last,
6214 null, null, mTmpNetworkStats);
6215 mTmpNetworkStats = delta;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006216
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006217 long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked(
6218 elapsedRealtimeMs);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006219 long totalPackets = delta.getTotalPackets();
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006220
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006221 final int size = delta.size();
6222 for (int i = 0; i < size; i++) {
6223 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006224
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006225 if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006226
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006227 final Uid u = getUidStatsLocked(mapUid(entry.uid));
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006228 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
6229 entry.rxPackets);
6230 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
6231 entry.txPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006232
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006233 if (radioTime > 0) {
6234 // Distribute total radio active time in to this app.
6235 long appPackets = entry.rxPackets + entry.txPackets;
6236 long appRadioTime = (radioTime*appPackets)/totalPackets;
6237 u.noteMobileRadioActiveTimeLocked(appRadioTime);
6238 // Remove this app from the totals, so that we don't lose any time
6239 // due to rounding.
6240 radioTime -= appRadioTime;
6241 totalPackets -= appPackets;
6242 }
6243
6244 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
6245 entry.rxBytes);
6246 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
6247 entry.txBytes);
6248 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
6249 entry.rxPackets);
6250 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
6251 entry.txPackets);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006252 }
6253
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006254 if (radioTime > 0) {
6255 // Whoops, there is some radio time we can't blame on an app!
6256 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
6257 mMobileRadioActiveUnknownCount.addCountLocked(1);
6258 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006259 }
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006260 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006261
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006262 if ((which&NET_UPDATE_WIFI) != 0 && mWifiIfaces.length > 0) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006263 final NetworkStats snapshot;
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006264 final NetworkStats last = mCurWifiSnapshot;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006265 try {
6266 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
6267 mWifiIfaces, NetworkStats.TAG_NONE, mLastWifiSnapshot);
6268 } catch (IOException e) {
6269 Log.wtf(TAG, "Failed to read wifi network stats", e);
6270 return;
6271 }
6272
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006273 mCurWifiSnapshot = snapshot;
6274 mLastWifiSnapshot = last;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006275
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006276 if (mOnBatteryInternal) {
6277 final NetworkStats delta = NetworkStats.subtract(snapshot, last,
6278 null, null, mTmpNetworkStats);
6279 mTmpNetworkStats = delta;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006280
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006281 final int size = delta.size();
6282 for (int i = 0; i < size; i++) {
6283 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08006284
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006285 if (DEBUG) {
6286 final NetworkStats.Entry cur = snapshot.getValues(i, null);
6287 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
6288 + " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes
6289 + " tx=" + cur.txBytes);
6290 }
6291
6292 if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
6293
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006294 final Uid u = getUidStatsLocked(mapUid(entry.uid));
Dianne Hackborn77b987f2014-02-26 16:20:52 -08006295 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
6296 entry.rxPackets);
6297 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
6298 entry.txPackets);
6299
6300 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
6301 entry.rxBytes);
6302 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
6303 entry.txBytes);
6304 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
6305 entry.rxPackets);
6306 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
6307 entry.txPackets);
Dianne Hackbornfb7b50a2014-02-24 17:06:14 -08006308 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006309 }
6310 }
6311 }
6312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006313 public long getAwakeTimeBattery() {
6314 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
6315 }
6316
6317 public long getAwakeTimePlugged() {
6318 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
6319 }
6320
6321 @Override
6322 public long computeUptime(long curTime, int which) {
6323 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006324 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006325 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07006326 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006327 }
6328 return 0;
6329 }
6330
6331 @Override
6332 public long computeRealtime(long curTime, int which) {
6333 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006334 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006335 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07006336 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 }
6338 return 0;
6339 }
6340
6341 @Override
6342 public long computeBatteryUptime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006343 return mOnBatteryTimeBase.computeUptime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006344 }
6345
6346 @Override
6347 public long computeBatteryRealtime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006348 return mOnBatteryTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006349 }
6350
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006351 @Override
6352 public long computeBatteryScreenOffUptime(long curTime, int which) {
6353 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
6354 }
6355
6356 @Override
6357 public long computeBatteryScreenOffRealtime(long curTime, int which) {
6358 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006359 }
6360
Dianne Hackborn260c5022014-04-29 11:23:16 -07006361 private long computeTimePerLevel(long[] steps, int numSteps) {
6362 // For now we'll do a simple average across all steps.
6363 if (numSteps <= 0) {
6364 return -1;
6365 }
6366 long total = 0;
6367 for (int i=0; i<numSteps; i++) {
6368 total += steps[i];
6369 }
6370 return total / numSteps;
6371 /*
6372 long[] buckets = new long[numSteps];
6373 int numBuckets = 0;
6374 int numToAverage = 4;
6375 int i = 0;
6376 while (i < numSteps) {
6377 long totalTime = 0;
6378 int num = 0;
6379 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
6380 totalTime += steps[i+j];
6381 num++;
6382 }
6383 buckets[numBuckets] = totalTime / num;
6384 numBuckets++;
6385 numToAverage *= 2;
6386 i += num;
6387 }
6388 if (numBuckets < 1) {
6389 return -1;
6390 }
6391 long averageTime = buckets[numBuckets-1];
6392 for (i=numBuckets-2; i>=0; i--) {
6393 averageTime = (averageTime + buckets[i]) / 2;
6394 }
6395 return averageTime;
6396 */
6397 }
6398
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006399 @Override
6400 public long computeBatteryTimeRemaining(long curTime) {
6401 if (!mOnBattery) {
6402 return -1;
6403 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07006404 /* Simple implementation just looks at the average discharge per level across the
6405 entire sample period.
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006406 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2;
6407 if (discharge < 2) {
6408 return -1;
6409 }
6410 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED);
6411 if (duration < 1000*1000) {
6412 return -1;
6413 }
6414 long usPerLevel = duration/discharge;
6415 return usPerLevel * mCurrentBatteryLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -07006416 */
6417 if (mNumDischargeStepDurations < 1) {
6418 return -1;
6419 }
6420 long msPerLevel = computeTimePerLevel(mDischargeStepDurations, mNumDischargeStepDurations);
6421 if (msPerLevel <= 0) {
6422 return -1;
6423 }
6424 return (msPerLevel * mCurrentBatteryLevel) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006425 }
6426
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07006427 public int getNumDischargeStepDurations() {
6428 return mNumDischargeStepDurations;
6429 }
6430
6431 public long[] getDischargeStepDurationsArray() {
6432 return mDischargeStepDurations;
6433 }
6434
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006435 @Override
6436 public long computeChargeTimeRemaining(long curTime) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07006437 if (mOnBattery) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006438 // Not yet working.
6439 return -1;
6440 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07006441 /* Broken
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006442 int curLevel = mCurrentBatteryLevel;
6443 int plugLevel = mDischargePlugLevel;
6444 if (plugLevel < 0 || curLevel < (plugLevel+1)) {
6445 return -1;
6446 }
6447 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED);
6448 if (duration < 1000*1000) {
6449 return -1;
6450 }
6451 long usPerLevel = duration/(curLevel-plugLevel);
6452 return usPerLevel * (100-curLevel);
Dianne Hackborn260c5022014-04-29 11:23:16 -07006453 */
6454 if (mNumChargeStepDurations < 1) {
6455 return -1;
6456 }
6457 long msPerLevel = computeTimePerLevel(mChargeStepDurations, mNumChargeStepDurations);
6458 if (msPerLevel <= 0) {
6459 return -1;
6460 }
6461 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006462 }
6463
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07006464 public int getNumChargeStepDurations() {
6465 return mNumChargeStepDurations;
6466 }
6467
6468 public long[] getChargeStepDurationsArray() {
6469 return mChargeStepDurations;
6470 }
6471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006472 long getBatteryUptimeLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006473 return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006474 }
6475
6476 @Override
6477 public long getBatteryUptime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006478 return mOnBatteryTimeBase.getUptime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006479 }
6480
6481 @Override
6482 public long getBatteryRealtime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006483 return mOnBatteryTimeBase.getRealtime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07006485
The Android Open Source Project10592532009-03-18 17:39:46 -07006486 @Override
Evan Millar633a1742009-04-02 16:36:33 -07006487 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07006488 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07006489 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07006490 }
6491 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006492
Evan Millar633a1742009-04-02 16:36:33 -07006493 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006494 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07006495 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006496
The Android Open Source Project10592532009-03-18 17:39:46 -07006497 @Override
Evan Millar633a1742009-04-02 16:36:33 -07006498 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07006499 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07006500 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07006501 }
6502 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006503
Evan Millar633a1742009-04-02 16:36:33 -07006504 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08006505 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07006506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006507
Amith Yamasanie43530a2009-08-21 13:11:37 -07006508 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006509 public int getLowDischargeAmountSinceCharge() {
6510 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08006511 int val = mLowDischargeAmountSinceCharge;
6512 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
6513 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
6514 }
6515 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006516 }
6517 }
6518
6519 @Override
6520 public int getHighDischargeAmountSinceCharge() {
6521 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08006522 int val = mHighDischargeAmountSinceCharge;
6523 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
6524 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
6525 }
6526 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006527 }
6528 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07006529
6530 @Override
6531 public int getDischargeAmount(int which) {
6532 int dischargeAmount = which == STATS_SINCE_CHARGED
6533 ? getHighDischargeAmountSinceCharge()
6534 : (getDischargeStartLevel() - getDischargeCurrentLevel());
6535 if (dischargeAmount < 0) {
6536 dischargeAmount = 0;
6537 }
6538 return dischargeAmount;
6539 }
6540
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006541 public int getDischargeAmountScreenOn() {
6542 synchronized(this) {
6543 int val = mDischargeAmountScreenOn;
Jeff Browne95c3cd2014-05-02 16:59:26 -07006544 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006545 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
6546 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
6547 }
6548 return val;
6549 }
6550 }
6551
6552 public int getDischargeAmountScreenOnSinceCharge() {
6553 synchronized(this) {
6554 int val = mDischargeAmountScreenOnSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07006555 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006556 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
6557 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
6558 }
6559 return val;
6560 }
6561 }
6562
6563 public int getDischargeAmountScreenOff() {
6564 synchronized(this) {
6565 int val = mDischargeAmountScreenOff;
Jeff Browne95c3cd2014-05-02 16:59:26 -07006566 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006567 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
6568 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
6569 }
6570 return val;
6571 }
6572 }
6573
6574 public int getDischargeAmountScreenOffSinceCharge() {
6575 synchronized(this) {
6576 int val = mDischargeAmountScreenOffSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07006577 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006578 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
6579 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
6580 }
6581 return val;
6582 }
6583 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006584
6585 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07006586 public int getCpuSpeedSteps() {
6587 return sNumSpeedSteps;
6588 }
6589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006590 /**
6591 * Retrieve the statistics object for a particular uid, creating if needed.
6592 */
6593 public Uid getUidStatsLocked(int uid) {
6594 Uid u = mUidStats.get(uid);
6595 if (u == null) {
6596 u = new Uid(uid);
6597 mUidStats.put(uid, u);
6598 }
6599 return u;
6600 }
6601
6602 /**
6603 * Remove the statistics object for a particular uid.
6604 */
6605 public void removeUidStatsLocked(int uid) {
6606 mUidStats.remove(uid);
6607 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07006608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006609 /**
6610 * Retrieve the statistics object for a particular process, creating
6611 * if needed.
6612 */
6613 public Uid.Proc getProcessStatsLocked(int uid, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006614 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006615 Uid u = getUidStatsLocked(uid);
6616 return u.getProcessStatsLocked(name);
6617 }
6618
6619 /**
6620 * Retrieve the statistics object for a particular process, creating
6621 * if needed.
6622 */
6623 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006624 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006625 Uid u = getUidStatsLocked(uid);
6626 return u.getPackageStatsLocked(pkg);
6627 }
6628
6629 /**
6630 * Retrieve the statistics object for a particular service, creating
6631 * if needed.
6632 */
6633 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07006634 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006635 Uid u = getUidStatsLocked(uid);
6636 return u.getServiceStatsLocked(pkg, name);
6637 }
6638
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006639 /**
6640 * Massage data to distribute any reasonable work down to more specific
6641 * owners. Must only be called on a dead BatteryStats object!
6642 */
6643 public void distributeWorkLocked(int which) {
6644 // Aggregate all CPU time associated with WIFI.
6645 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
6646 if (wifiUid != null) {
6647 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
6648 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
6649 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
6650 for (int i=0; i<mUidStats.size(); i++) {
6651 Uid uid = mUidStats.valueAt(i);
6652 if (uid.mUid != Process.WIFI_UID) {
6653 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
6654 if (uidRunningTime > 0) {
6655 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
6656 long time = proc.getUserTime(which);
6657 time = (time*uidRunningTime)/totalRunningTime;
6658 uidProc.mUserTime += time;
6659 proc.mUserTime -= time;
6660 time = proc.getSystemTime(which);
6661 time = (time*uidRunningTime)/totalRunningTime;
6662 uidProc.mSystemTime += time;
6663 proc.mSystemTime -= time;
6664 time = proc.getForegroundTime(which);
6665 time = (time*uidRunningTime)/totalRunningTime;
6666 uidProc.mForegroundTime += time;
6667 proc.mForegroundTime -= time;
6668 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
6669 SamplingCounter sc = proc.mSpeedBins[sb];
6670 if (sc != null) {
6671 time = sc.getCountLocked(which);
6672 time = (time*uidRunningTime)/totalRunningTime;
6673 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
6674 if (uidSc == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006675 uidSc = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006676 uidProc.mSpeedBins[sb] = uidSc;
6677 }
6678 uidSc.mCount.addAndGet((int)time);
6679 sc.mCount.addAndGet((int)-time);
6680 }
6681 }
6682 totalRunningTime -= uidRunningTime;
6683 }
6684 }
6685 }
6686 }
6687 }
6688 }
6689
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006690 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006691 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006692 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006693 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006694
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006695 Parcel mPendingWrite = null;
6696 final ReentrantLock mWriteLock = new ReentrantLock();
6697
6698 public void writeAsyncLocked() {
6699 writeLocked(false);
6700 }
6701
6702 public void writeSyncLocked() {
6703 writeLocked(true);
6704 }
6705
6706 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006707 if (mFile == null) {
6708 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006709 return;
6710 }
6711
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006712 if (mShuttingDown) {
6713 return;
6714 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006715
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006716 Parcel out = Parcel.obtain();
6717 writeSummaryToParcel(out);
6718 mLastWriteTime = SystemClock.elapsedRealtime();
6719
6720 if (mPendingWrite != null) {
6721 mPendingWrite.recycle();
6722 }
6723 mPendingWrite = out;
6724
6725 if (sync) {
6726 commitPendingDataToDisk();
6727 } else {
6728 Thread thr = new Thread("BatteryStats-Write") {
6729 @Override
6730 public void run() {
6731 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
6732 commitPendingDataToDisk();
6733 }
6734 };
6735 thr.start();
6736 }
6737 }
6738
6739 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07006740 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006741 synchronized (this) {
6742 next = mPendingWrite;
6743 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07006744 if (next == null) {
6745 return;
6746 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006747
6748 mWriteLock.lock();
6749 }
6750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006751 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006752 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006753 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006754 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006755 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006756 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006757 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006759 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006760 mFile.rollback();
6761 } finally {
6762 next.recycle();
6763 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07006764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006765 }
6766
6767 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
6768 int pos = 0;
6769 int avail = stream.available();
6770 byte[] data = new byte[avail];
6771 while (true) {
6772 int amt = stream.read(data, pos, data.length-pos);
6773 //Log.i("foo", "Read " + amt + " bytes at " + pos
6774 // + " of avail " + data.length);
6775 if (amt <= 0) {
6776 //Log.i("foo", "**** FINISHED READING: pos=" + pos
6777 // + " len=" + data.length);
6778 return data;
6779 }
6780 pos += amt;
6781 avail = stream.available();
6782 if (avail > data.length-pos) {
6783 byte[] newData = new byte[pos+avail];
6784 System.arraycopy(data, 0, newData, 0, pos);
6785 data = newData;
6786 }
6787 }
6788 }
6789
6790 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006791 if (mFile == null) {
6792 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006793 return;
6794 }
6795
6796 mUidStats.clear();
6797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006798 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006799 File file = mFile.chooseForRead();
6800 if (!file.exists()) {
6801 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006802 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006803 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006804
6805 byte[] raw = readFully(stream);
6806 Parcel in = Parcel.obtain();
6807 in.unmarshall(raw, 0, raw.length);
6808 in.setDataPosition(0);
6809 stream.close();
6810
6811 readSummaryFromParcel(in);
Dianne Hackborn00e25212014-02-19 10:49:24 -08006812 } catch(Exception e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006813 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006814 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006815
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006816 if (mHistoryBuffer.dataPosition() > 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006817 mRecordingHistory = true;
Dianne Hackborn40c87252014-03-19 16:55:40 -07006818 final long elapsedRealtime = SystemClock.elapsedRealtime();
6819 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006820 if (USE_OLD_HISTORY) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006821 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006822 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006823 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
6824 startRecordingHistory(elapsedRealtime, uptime, false);
Dianne Hackborne8c88e62011-08-17 19:09:09 -07006825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006826 }
6827
6828 public int describeContents() {
6829 return 0;
6830 }
6831
Dianne Hackbornae384452011-06-28 12:33:48 -07006832 void readHistory(Parcel in, boolean andOldHistory) {
6833 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006834
6835 mHistoryBuffer.setDataSize(0);
6836 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006837 mHistoryTagPool.clear();
6838 mNextHistoryTagIdx = 0;
6839 mNumHistoryTagChars = 0;
Dianne Hackborn099bc622014-01-22 13:39:16 -08006840
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006841 int numTags = in.readInt();
6842 for (int i=0; i<numTags; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08006843 int idx = in.readInt();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006844 String str = in.readString();
6845 int uid = in.readInt();
6846 HistoryTag tag = new HistoryTag();
6847 tag.string = str;
6848 tag.uid = uid;
6849 tag.poolIdx = idx;
6850 mHistoryTagPool.put(tag, idx);
6851 if (idx >= mNextHistoryTagIdx) {
6852 mNextHistoryTagIdx = idx+1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08006853 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006854 mNumHistoryTagChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08006855 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006856
6857 int bufSize = in.readInt();
6858 int curPos = in.dataPosition();
6859 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
6860 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
6861 } else if ((bufSize&~3) != bufSize) {
6862 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
6863 } else {
6864 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
6865 + " bytes at " + curPos);
6866 mHistoryBuffer.appendFrom(in, curPos, bufSize);
6867 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006868 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006869
Dianne Hackbornae384452011-06-28 12:33:48 -07006870 if (andOldHistory) {
6871 readOldHistory(in);
6872 }
6873
6874 if (DEBUG_HISTORY) {
6875 StringBuilder sb = new StringBuilder(128);
6876 sb.append("****************** OLD mHistoryBaseTime: ");
6877 TimeUtils.formatDuration(mHistoryBaseTime, sb);
6878 Slog.i(TAG, sb.toString());
6879 }
6880 mHistoryBaseTime = historyBaseTime;
6881 if (DEBUG_HISTORY) {
6882 StringBuilder sb = new StringBuilder(128);
6883 sb.append("****************** NEW mHistoryBaseTime: ");
6884 TimeUtils.formatDuration(mHistoryBaseTime, sb);
6885 Slog.i(TAG, sb.toString());
6886 }
6887
6888 // We are just arbitrarily going to insert 1 minute from the sample of
6889 // the last run until samples in this run.
6890 if (mHistoryBaseTime > 0) {
6891 long oldnow = SystemClock.elapsedRealtime();
6892 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000;
6893 if (DEBUG_HISTORY) {
6894 StringBuilder sb = new StringBuilder(128);
6895 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
6896 TimeUtils.formatDuration(mHistoryBaseTime, sb);
6897 Slog.i(TAG, sb.toString());
6898 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07006899 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006900 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006901
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006902 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07006903 if (!USE_OLD_HISTORY) {
6904 return;
6905 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006906 mHistory = mHistoryEnd = mHistoryCache = null;
6907 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07006908 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006909 HistoryItem rec = new HistoryItem(time, in);
6910 addHistoryRecordLocked(rec);
6911 }
6912 }
6913
Dianne Hackbornae384452011-06-28 12:33:48 -07006914 void writeHistory(Parcel out, boolean andOldHistory) {
6915 if (DEBUG_HISTORY) {
6916 StringBuilder sb = new StringBuilder(128);
6917 sb.append("****************** WRITING mHistoryBaseTime: ");
6918 TimeUtils.formatDuration(mHistoryBaseTime, sb);
Dianne Hackborn40c87252014-03-19 16:55:40 -07006919 sb.append(" mLastHistoryElapsedRealtime: ");
6920 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
Dianne Hackbornae384452011-06-28 12:33:48 -07006921 Slog.i(TAG, sb.toString());
6922 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07006923 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006924 out.writeInt(mHistoryTagPool.size());
6925 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
6926 HistoryTag tag = ent.getKey();
Dianne Hackborn099bc622014-01-22 13:39:16 -08006927 out.writeInt(ent.getValue());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08006928 out.writeString(tag.string);
6929 out.writeInt(tag.uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08006930 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006931 out.writeInt(mHistoryBuffer.dataSize());
6932 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
6933 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
6934 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07006935
6936 if (andOldHistory) {
6937 writeOldHistory(out);
6938 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006939 }
6940
6941 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07006942 if (!USE_OLD_HISTORY) {
6943 return;
6944 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006945 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006946 while (rec != null) {
6947 if (rec.time >= 0) rec.writeToParcel(out, 0);
6948 rec = rec.next;
6949 }
6950 out.writeLong(-1);
6951 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006953 private void readSummaryFromParcel(Parcel in) {
6954 final int version = in.readInt();
6955 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006956 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 + ", expected " + VERSION + "; erasing old stats");
6958 return;
6959 }
6960
Dianne Hackbornae384452011-06-28 12:33:48 -07006961 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006963 mStartCount = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006964 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006965 mRealtime = in.readLong();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08006966 mStartClockTime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006967 mOnBatteryTimeBase.readSummaryFromParcel(in);
6968 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006969 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006970 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07006971 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006972 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006973 mLowDischargeAmountSinceCharge = in.readInt();
6974 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006975 mDischargeAmountScreenOnSinceCharge = in.readInt();
6976 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackborn260c5022014-04-29 11:23:16 -07006977 mNumDischargeStepDurations = in.readInt();
6978 in.readLongArray(mDischargeStepDurations);
6979 mNumChargeStepDurations = in.readInt();
6980 in.readLongArray(mChargeStepDurations);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006982 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006983
Jeff Browne95c3cd2014-05-02 16:59:26 -07006984 mScreenState = Display.STATE_UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006985 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006986 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
6987 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
6988 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07006989 mInteractive = false;
6990 mInteractiveTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006991 mPhoneOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006992 mLowPowerModeEnabledTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006993 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08006994 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07006995 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
6996 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07006997 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006998 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
6999 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
7000 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007001 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007002 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
7003 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007004 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007005 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007006 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08007007 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007008 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007009 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
7010 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07007011 mWifiOn = false;
7012 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007013 mGlobalWifiRunning = false;
7014 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007015 for (int i=0; i<NUM_WIFI_STATES; i++) {
7016 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
7017 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007018 mBluetoothOn = false;
7019 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007020 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
7021 mBluetoothStateTimer[i].readSummaryFromParcelLocked(in);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007022 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023
Evan Millarc64edde2009-04-18 12:26:32 -07007024 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007025 if (NKW > 10000) {
7026 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
7027 return;
7028 }
Evan Millarc64edde2009-04-18 12:26:32 -07007029 for (int ikw = 0; ikw < NKW; ikw++) {
7030 if (in.readInt() != 0) {
7031 String kwltName = in.readString();
7032 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
7033 }
7034 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07007035
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007036 int NWR = in.readInt();
7037 if (NWR > 10000) {
7038 Slog.w(TAG, "File corrupt: too many wakeup reasons " + NWR);
7039 return;
7040 }
7041 for (int iwr = 0; iwr < NWR; iwr++) {
7042 if (in.readInt() != 0) {
7043 String reasonName = in.readString();
7044 getWakeupReasonCounterLocked(reasonName).readSummaryFromParcelLocked(in);
7045 }
7046 }
7047
Amith Yamasanie43530a2009-08-21 13:11:37 -07007048 sNumSpeedSteps = in.readInt();
Dianne Hackborn00e25212014-02-19 10:49:24 -08007049 if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) {
7050 throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps);
7051 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07007052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007053 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007054 if (NU > 10000) {
7055 Slog.w(TAG, "File corrupt: too many uids " + NU);
7056 return;
7057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007058 for (int iu = 0; iu < NU; iu++) {
7059 int uid = in.readInt();
7060 Uid u = new Uid(uid);
7061 mUidStats.put(uid, u);
7062
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007063 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007064 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007065 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007066 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007067 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007068 if (in.readInt() != 0) {
7069 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
7070 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07007071 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007072 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07007073 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007074 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07007075 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
7076 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7077 if (in.readInt() != 0) {
7078 u.makeWifiBatchedScanBin(i, null);
7079 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
7080 }
7081 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07007082 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007083 if (in.readInt() != 0) {
7084 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
7085 }
7086 u.mAudioTurnedOn = false;
7087 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007088 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007089 }
7090 u.mVideoTurnedOn = false;
7091 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007092 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
7093 }
7094 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007095 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
7096 }
7097 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007098 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007099 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07007100
Dianne Hackborn617f8772009-03-31 15:04:46 -07007101 if (in.readInt() != 0) {
7102 if (u.mUserActivityCounters == null) {
7103 u.initUserActivityLocked();
7104 }
7105 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
7106 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
7107 }
7108 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007109
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007110 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007111 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007112 u.initNetworkActivityLocked();
7113 }
7114 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007115 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
7116 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007117 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007118 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
7119 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007120 }
7121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007122 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007123 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007124 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
7125 return;
7126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007127 for (int iw = 0; iw < NW; iw++) {
7128 String wlName = in.readString();
7129 if (in.readInt() != 0) {
7130 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
7131 }
7132 if (in.readInt() != 0) {
7133 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
7134 }
7135 if (in.readInt() != 0) {
7136 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
7137 }
7138 }
7139
7140 int 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 sensors " + NP);
7143 return;
7144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007145 for (int is = 0; is < NP; is++) {
7146 int seNumber = in.readInt();
7147 if (in.readInt() != 0) {
7148 u.getSensorTimerLocked(seNumber, true)
7149 .readSummaryFromParcelLocked(in);
7150 }
7151 }
7152
7153 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007154 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007155 Slog.w(TAG, "File corrupt: too many processes " + NP);
7156 return;
7157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007158 for (int ip = 0; ip < NP; ip++) {
7159 String procName = in.readString();
7160 Uid.Proc p = u.getProcessStatsLocked(procName);
7161 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007162 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007163 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007164 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007165 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007166 if (NSB > 100) {
7167 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
7168 return;
7169 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007170 p.mSpeedBins = new SamplingCounter[NSB];
7171 for (int i=0; i<NSB; i++) {
7172 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007173 p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007174 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
7175 }
7176 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007177 if (!p.readExcessivePowerFromParcelLocked(in)) {
7178 return;
7179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007180 }
7181
7182 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07007183 if (NP > 10000) {
7184 Slog.w(TAG, "File corrupt: too many packages " + NP);
7185 return;
7186 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007187 for (int ip = 0; ip < NP; ip++) {
7188 String pkgName = in.readString();
7189 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
7190 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007191 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007192 if (NS > 1000) {
7193 Slog.w(TAG, "File corrupt: too many services " + NS);
7194 return;
7195 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007196 for (int is = 0; is < NS; is++) {
7197 String servName = in.readString();
7198 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
7199 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007200 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007201 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007202 }
7203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007204 }
7205 }
7206
7207 /**
7208 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
7209 * disk. This format does not allow a lossless round-trip.
7210 *
7211 * @param out the Parcel to be written to.
7212 */
7213 public void writeSummaryToParcel(Parcel out) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007214 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007216 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
7217 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007218
7219 out.writeInt(VERSION);
7220
Dianne Hackbornae384452011-06-28 12:33:48 -07007221 writeHistory(out, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007223 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007224 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007225 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007226 out.writeLong(mStartClockTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007227 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
7228 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007229 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007230 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07007231 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007232 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08007233 out.writeInt(getLowDischargeAmountSinceCharge());
7234 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007235 out.writeInt(getDischargeAmountScreenOnSinceCharge());
7236 out.writeInt(getDischargeAmountScreenOffSinceCharge());
Dianne Hackborn260c5022014-04-29 11:23:16 -07007237 out.writeInt(mNumDischargeStepDurations);
7238 out.writeLongArray(mDischargeStepDurations);
7239 out.writeInt(mNumChargeStepDurations);
7240 out.writeLongArray(mChargeStepDurations);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007241
7242 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007243 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007244 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007245 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007246 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007247 mLowPowerModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007248 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Wink Saville52840902011-02-18 12:40:47 -08007249 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007250 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07007251 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007252 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07007253 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007254 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07007255 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007256 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007257 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
7258 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007259 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007260 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
7261 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007262 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007263 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
7264 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007265 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
7266 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007267 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007268 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007269 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007270 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007271 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007272 mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007273 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007274
Evan Millarc64edde2009-04-18 12:26:32 -07007275 out.writeInt(mKernelWakelockStats.size());
7276 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
7277 Timer kwlt = ent.getValue();
7278 if (kwlt != null) {
7279 out.writeInt(1);
7280 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007281 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
7282 } else {
7283 out.writeInt(0);
7284 }
7285 }
7286
7287 out.writeInt(mWakeupReasonStats.size());
7288 for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) {
7289 LongSamplingCounter counter = ent.getValue();
7290 if (counter != null) {
7291 out.writeInt(1);
7292 out.writeString(ent.getKey());
7293 counter.writeSummaryFromParcelLocked(out);
Evan Millarc64edde2009-04-18 12:26:32 -07007294 } else {
7295 out.writeInt(0);
7296 }
7297 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007298
Amith Yamasanie43530a2009-08-21 13:11:37 -07007299 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007300 final int NU = mUidStats.size();
7301 out.writeInt(NU);
7302 for (int iu = 0; iu < NU; iu++) {
7303 out.writeInt(mUidStats.keyAt(iu));
7304 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007305
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007306 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007307 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007308 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007309 } else {
7310 out.writeInt(0);
7311 }
7312 if (u.mFullWifiLockTimer != null) {
7313 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007314 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007315 } else {
7316 out.writeInt(0);
7317 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07007318 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007319 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007320 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007321 } else {
7322 out.writeInt(0);
7323 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07007324 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7325 if (u.mWifiBatchedScanTimer[i] != null) {
7326 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007327 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Robert Greenwalta029ea12013-09-25 16:38:12 -07007328 } else {
7329 out.writeInt(0);
7330 }
7331 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007332 if (u.mWifiMulticastTimer != null) {
7333 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007334 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007335 } else {
7336 out.writeInt(0);
7337 }
7338 if (u.mAudioTurnedOnTimer != null) {
7339 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007340 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007341 } else {
7342 out.writeInt(0);
7343 }
7344 if (u.mVideoTurnedOnTimer != null) {
7345 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007346 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007347 } else {
7348 out.writeInt(0);
7349 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007350 if (u.mForegroundActivityTimer != null) {
7351 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007352 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007353 } else {
7354 out.writeInt(0);
7355 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007356 if (u.mVibratorOnTimer != null) {
7357 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007358 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007359 } else {
7360 out.writeInt(0);
7361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007362
Dianne Hackborn617f8772009-03-31 15:04:46 -07007363 if (u.mUserActivityCounters == null) {
7364 out.writeInt(0);
7365 } else {
7366 out.writeInt(1);
7367 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
7368 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
7369 }
7370 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007371
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007372 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007373 out.writeInt(0);
7374 } else {
7375 out.writeInt(1);
7376 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007377 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
7378 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007379 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007380 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
7381 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007382 }
7383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007384 int NW = u.mWakelockStats.size();
7385 out.writeInt(NW);
7386 if (NW > 0) {
7387 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
7388 : u.mWakelockStats.entrySet()) {
7389 out.writeString(ent.getKey());
7390 Uid.Wakelock wl = ent.getValue();
7391 if (wl.mTimerFull != null) {
7392 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007393 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007394 } else {
7395 out.writeInt(0);
7396 }
7397 if (wl.mTimerPartial != null) {
7398 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007399 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007400 } else {
7401 out.writeInt(0);
7402 }
7403 if (wl.mTimerWindow != null) {
7404 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007405 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 } else {
7407 out.writeInt(0);
7408 }
7409 }
7410 }
7411
7412 int NSE = u.mSensorStats.size();
7413 out.writeInt(NSE);
7414 if (NSE > 0) {
7415 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
7416 : u.mSensorStats.entrySet()) {
7417 out.writeInt(ent.getKey());
7418 Uid.Sensor se = ent.getValue();
7419 if (se.mTimer != null) {
7420 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007421 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007422 } else {
7423 out.writeInt(0);
7424 }
7425 }
7426 }
7427
7428 int NP = u.mProcessStats.size();
7429 out.writeInt(NP);
7430 if (NP > 0) {
7431 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
7432 : u.mProcessStats.entrySet()) {
7433 out.writeString(ent.getKey());
7434 Uid.Proc ps = ent.getValue();
7435 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007436 out.writeLong(ps.mSystemTime);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007437 out.writeLong(ps.mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007438 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007439 final int N = ps.mSpeedBins.length;
7440 out.writeInt(N);
7441 for (int i=0; i<N; i++) {
7442 if (ps.mSpeedBins[i] != null) {
7443 out.writeInt(1);
7444 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
7445 } else {
7446 out.writeInt(0);
7447 }
7448 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007449 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007450 }
7451 }
7452
7453 NP = u.mPackageStats.size();
7454 out.writeInt(NP);
7455 if (NP > 0) {
7456 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
7457 : u.mPackageStats.entrySet()) {
7458 out.writeString(ent.getKey());
7459 Uid.Pkg ps = ent.getValue();
7460 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007461 final int NS = ps.mServiceStats.size();
7462 out.writeInt(NS);
7463 if (NS > 0) {
7464 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
7465 : ps.mServiceStats.entrySet()) {
7466 out.writeString(sent.getKey());
7467 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007468 long time = ss.getStartTimeToNowLocked(
7469 mOnBatteryTimeBase.getUptime(NOW_SYS));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007470 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007471 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007472 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007473 }
7474 }
7475 }
7476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007477 }
7478 }
7479
7480 public void readFromParcel(Parcel in) {
7481 readFromParcelLocked(in);
7482 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007484 void readFromParcelLocked(Parcel in) {
7485 int magic = in.readInt();
7486 if (magic != MAGIC) {
7487 throw new ParcelFormatException("Bad magic number");
7488 }
7489
Dianne Hackbornae384452011-06-28 12:33:48 -07007490 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007492 mStartCount = in.readInt();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007493 mStartClockTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007494 mUptime = in.readLong();
7495 mUptimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007496 mRealtime = in.readLong();
7497 mRealtimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007498 mOnBattery = in.readInt() != 0;
7499 mOnBatteryInternal = false; // we are no longer really running.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007500 mOnBatteryTimeBase.readFromParcel(in);
7501 mOnBatteryScreenOffTimeBase.readFromParcel(in);
7502
Jeff Browne95c3cd2014-05-02 16:59:26 -07007503 mScreenState = Display.STATE_UNKNOWN;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007504 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase, in);
7505 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
7506 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase,
7507 in);
7508 }
Dianne Hackborn29325132014-05-21 15:01:03 -07007509 mInteractive = false;
7510 mInteractiveTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007511 mPhoneOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007512 mLowPowerModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
7513 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007514 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
7515 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
7516 null, mOnBatteryTimeBase, in);
7517 }
7518 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase, in);
7519 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
7520 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
7521 null, mOnBatteryTimeBase, in);
7522 }
7523 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
7524 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
7525 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
7526 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007527 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007528 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in);
7529 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase,
7530 in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007531 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007532 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
7533 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
7534 mWifiOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007535 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007536 mGlobalWifiRunning = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007537 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007538 for (int i=0; i<NUM_WIFI_STATES; i++) {
7539 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
7540 null, mOnBatteryTimeBase, in);
7541 }
7542 mBluetoothOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007543 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007544 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
7545 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i,
7546 null, mOnBatteryTimeBase, in);
7547 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007548 mAudioOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007549 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
Jeff Browne95c3cd2014-05-02 16:59:26 -07007550 mVideoOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007551 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007552 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007553 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07007554 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007555 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007556 mLowDischargeAmountSinceCharge = in.readInt();
7557 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007558 mDischargeAmountScreenOn = in.readInt();
7559 mDischargeAmountScreenOnSinceCharge = in.readInt();
7560 mDischargeAmountScreenOff = in.readInt();
7561 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackborn260c5022014-04-29 11:23:16 -07007562 mNumDischargeStepDurations = in.readInt();
7563 in.readLongArray(mDischargeStepDurations);
7564 mNumChargeStepDurations = in.readInt();
7565 in.readLongArray(mChargeStepDurations);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007566 mLastWriteTime = in.readLong();
7567
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07007568 mBluetoothPingCount = in.readInt();
7569 mBluetoothPingStart = -1;
7570
Evan Millarc64edde2009-04-18 12:26:32 -07007571 mKernelWakelockStats.clear();
7572 int NKW = in.readInt();
7573 for (int ikw = 0; ikw < NKW; ikw++) {
7574 if (in.readInt() != 0) {
7575 String wakelockName = in.readString();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007576 SamplingTimer kwlt = new SamplingTimer(mOnBatteryTimeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07007577 mKernelWakelockStats.put(wakelockName, kwlt);
7578 }
7579 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007580
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007581 mWakeupReasonStats.clear();
7582 int NWR = in.readInt();
7583 for (int iwr = 0; iwr < NWR; iwr++) {
7584 if (in.readInt() != 0) {
7585 String reasonName = in.readString();
7586 LongSamplingCounter counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase,
7587 in);
7588 mWakeupReasonStats.put(reasonName, counter);
7589 }
7590 }
7591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007592 mPartialTimers.clear();
7593 mFullTimers.clear();
7594 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007595 mWifiRunningTimers.clear();
7596 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -07007597 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -07007598 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007599 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007600
Amith Yamasanie43530a2009-08-21 13:11:37 -07007601 sNumSpeedSteps = in.readInt();
7602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007603 int numUids = in.readInt();
7604 mUidStats.clear();
7605 for (int i = 0; i < numUids; i++) {
7606 int uid = in.readInt();
7607 Uid u = new Uid(uid);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007608 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007609 mUidStats.append(uid, u);
7610 }
7611 }
7612
7613 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007614 writeToParcelLocked(out, true, flags);
7615 }
7616
7617 public void writeToParcelWithoutUids(Parcel out, int flags) {
7618 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007619 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007620
7621 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007622 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007623 // Need to update with current kernel wake lock counts.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007624 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007626 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
7627 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007628 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
7629 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007631 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007632
Dianne Hackbornae384452011-06-28 12:33:48 -07007633 writeHistory(out, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007635 out.writeInt(mStartCount);
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007636 out.writeLong(mStartClockTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007637 out.writeLong(mUptime);
7638 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007639 out.writeLong(mRealtime);
7640 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007641 out.writeInt(mOnBattery ? 1 : 0);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007642 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
7643 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
7644
7645 mScreenOnTimer.writeToParcel(out, uSecRealtime);
7646 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
7647 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
7648 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007649 mInteractiveTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007650 mLowPowerModeEnabledTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007651 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
7652 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
7653 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
7654 }
7655 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
7656 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
7657 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
7658 }
7659 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
7660 mNetworkByteActivityCounters[i].writeToParcel(out);
7661 mNetworkPacketActivityCounters[i].writeToParcel(out);
7662 }
7663 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
7664 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007665 mMobileRadioActiveAdjustedTime.writeToParcel(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007666 mMobileRadioActiveUnknownTime.writeToParcel(out);
7667 mMobileRadioActiveUnknownCount.writeToParcel(out);
7668 mWifiOnTimer.writeToParcel(out, uSecRealtime);
7669 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
7670 for (int i=0; i<NUM_WIFI_STATES; i++) {
7671 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
7672 }
7673 mBluetoothOnTimer.writeToParcel(out, uSecRealtime);
7674 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
7675 mBluetoothStateTimer[i].writeToParcel(out, uSecRealtime);
7676 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007677 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007678 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07007679 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007680 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007681 out.writeInt(mLowDischargeAmountSinceCharge);
7682 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007683 out.writeInt(mDischargeAmountScreenOn);
7684 out.writeInt(mDischargeAmountScreenOnSinceCharge);
7685 out.writeInt(mDischargeAmountScreenOff);
7686 out.writeInt(mDischargeAmountScreenOffSinceCharge);
Dianne Hackborn260c5022014-04-29 11:23:16 -07007687 out.writeInt(mNumDischargeStepDurations);
7688 out.writeLongArray(mDischargeStepDurations);
7689 out.writeInt(mNumChargeStepDurations);
7690 out.writeLongArray(mChargeStepDurations);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007691 out.writeLong(mLastWriteTime);
7692
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07007693 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07007694
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007695 if (inclUids) {
7696 out.writeInt(mKernelWakelockStats.size());
7697 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
7698 SamplingTimer kwlt = ent.getValue();
7699 if (kwlt != null) {
7700 out.writeInt(1);
7701 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007702 kwlt.writeToParcel(out, uSecRealtime);
7703 } else {
7704 out.writeInt(0);
7705 }
7706 }
7707 out.writeInt(mWakeupReasonStats.size());
7708 for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) {
7709 LongSamplingCounter counter = ent.getValue();
7710 if (counter != null) {
7711 out.writeInt(1);
7712 out.writeString(ent.getKey());
7713 counter.writeToParcel(out);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007714 } else {
7715 out.writeInt(0);
7716 }
Evan Millarc64edde2009-04-18 12:26:32 -07007717 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007718 } else {
7719 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07007720 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07007721
7722 out.writeInt(sNumSpeedSteps);
7723
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007724 if (inclUids) {
7725 int size = mUidStats.size();
7726 out.writeInt(size);
7727 for (int i = 0; i < size; i++) {
7728 out.writeInt(mUidStats.keyAt(i));
7729 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007730
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007731 uid.writeToParcelLocked(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07007732 }
7733 } else {
7734 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007735 }
7736 }
7737
7738 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
7739 new Parcelable.Creator<BatteryStatsImpl>() {
7740 public BatteryStatsImpl createFromParcel(Parcel in) {
7741 return new BatteryStatsImpl(in);
7742 }
7743
7744 public BatteryStatsImpl[] newArray(int size) {
7745 return new BatteryStatsImpl[size];
7746 }
7747 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007748
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007749 public void prepareForDumpLocked() {
7750 // Need to retrieve current kernel wake lock stats before printing.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007751 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007752 }
7753
Dianne Hackbornc51cf032014-03-02 19:08:15 -08007754 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007755 if (DEBUG) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007756 pw.println("mOnBatteryTimeBase:");
7757 mOnBatteryTimeBase.dump(pw, " ");
7758 pw.println("mOnBatteryScreenOffTimeBase:");
7759 mOnBatteryScreenOffTimeBase.dump(pw, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007760 Printer pr = new PrintWriterPrinter(pw);
7761 pr.println("*** Screen timer:");
7762 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07007763 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007764 pr.println("*** Screen brightness #" + i + ":");
7765 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07007766 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007767 pr.println("*** Interactive timer:");
7768 mInteractiveTimer.logState(pr, " ");
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07007769 pr.println("*** Low power mode timer:");
7770 mLowPowerModeEnabledTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007771 pr.println("*** Phone timer:");
7772 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08007773 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007774 pr.println("*** Signal strength #" + i + ":");
7775 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07007776 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07007777 pr.println("*** Signal scanning :");
7778 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07007779 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007780 pr.println("*** Data connection type #" + i + ":");
7781 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07007782 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007783 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007784 pr.println("*** Mobile network active timer:");
7785 mMobileRadioActiveTimer.logState(pr, " ");
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007786 pr.println("*** Mobile network active adjusted timer:");
7787 mMobileRadioActiveAdjustedTime.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007788 pr.println("*** Wifi timer:");
7789 mWifiOnTimer.logState(pr, " ");
7790 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007791 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007792 for (int i=0; i<NUM_WIFI_STATES; i++) {
7793 pr.println("*** Wifi state #" + i + ":");
7794 mWifiStateTimer[i].logState(pr, " ");
7795 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007796 pr.println("*** Bluetooth timer:");
7797 mBluetoothOnTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007798 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007799 pr.println("*** Bluetooth active type #" + i + ":");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007800 mBluetoothStateTimer[i].logState(pr, " ");
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007802 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08007803 super.dumpLocked(context, pw, flags, reqUid, histStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007805}