blob: 6375dbe6cf898e7f1ab8a78f0c477475c126e95e [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
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070019import static android.text.format.DateUtils.SECOND_IN_MILLIS;
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;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070024import android.net.ConnectivityManager;
25import android.net.NetworkStats;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070026import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.os.BatteryStats;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070028import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070029import android.os.Handler;
30import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.Parcel;
32import android.os.ParcelFormatException;
33import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070034import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.os.SystemClock;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080036import android.os.SystemProperties;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070037import android.os.WorkSource;
Amith Yamasanif37447b2009-10-08 18:28:01 -070038import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070039import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070040import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070042import android.util.LogWriter;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070043import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070045import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.util.SparseArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070047import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070049import com.android.internal.net.NetworkStatsFactory;
50import com.android.internal.util.JournaledFile;
51import com.google.android.collect.Sets;
52
Amith Yamasani3718aaa2009-06-09 06:32:35 -070053import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import java.io.File;
55import java.io.FileInputStream;
56import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070057import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070059import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import java.util.ArrayList;
61import java.util.HashMap;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070062import java.util.HashSet;
Evan Millarc64edde2009-04-18 12:26:32 -070063import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070064import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070066import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070067import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068
69/**
70 * All information we are collecting about things that can happen that impact
71 * battery life. All times are represented in microseconds except where indicated
72 * otherwise.
73 */
74public final class BatteryStatsImpl extends BatteryStats {
75 private static final String TAG = "BatteryStatsImpl";
76 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070077 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -070078 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070079
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070080 // TODO: remove "tcp" from network methods, since we measure total stats.
81
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070083 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084
85 // Current on-disk Parcel version
Dianne Hackborna06de0f2012-12-11 16:34:47 -080086 private static final int VERSION = 64 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -070087
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070088 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070089 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070090
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070091 // No, really, THIS is the maximum number of items we will record in the history.
92 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
93
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080094 // The maximum number of names wakelocks we will keep track of
95 // per uid; once the limit is reached, we batch the remaining wakelocks
96 // in to one common name.
Dianne Hackbornaf17baa2013-05-09 15:27:47 -070097 private static final int MAX_WAKELOCKS_PER_UID = 50;
Dianne Hackbornc24ab862011-10-18 15:55:03 -070098
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080099 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700100
Amith Yamasanie43530a2009-08-21 13:11:37 -0700101 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700103 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700105 static final int MSG_UPDATE_WAKELOCKS = 1;
106 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700107 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700108
109 public interface BatteryCallback {
110 public void batteryNeedsCpuUpdate();
111 public void batteryPowerChanged(boolean onBattery);
112 }
113
114 final class MyHandler extends Handler {
115 @Override
116 public void handleMessage(Message msg) {
117 BatteryCallback cb = mCallback;
118 switch (msg.what) {
119 case MSG_UPDATE_WAKELOCKS:
120 if (cb != null) {
121 cb.batteryNeedsCpuUpdate();
122 }
123 break;
124 case MSG_REPORT_POWER_CHANGE:
125 if (cb != null) {
126 cb.batteryPowerChanged(msg.arg1 != 0);
127 }
128 break;
129 }
130 }
131 }
132
133 private final MyHandler mHandler;
134
135 private BatteryCallback mCallback;
136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 /**
138 * The statistics we have collected organized by uids.
139 */
140 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
141 new SparseArray<BatteryStatsImpl.Uid>();
142
143 // A set of pools of currently active timers. When a timer is queried, we will divide the
144 // elapsed time by the number of active timers to arrive at that timer's share of the time.
145 // In order to do this, we must refresh each timer whenever the number of active timers
146 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700147 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
148 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
149 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
150 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
151 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700152 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
153 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700154 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
Nick Pelly6ccaa542012-06-15 15:22:47 -0700155 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700157 // Last partial timers we use for distributing CPU usage.
158 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 // These are the objects that will want to do something when the device
161 // is unplugged from power.
162 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700163
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700164 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700165
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700166 long mHistoryBaseTime;
167 boolean mHaveBatteryLevel = false;
168 boolean mRecordingHistory = true;
169 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700170
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700171 static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
172 static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700173 final Parcel mHistoryBuffer = Parcel.obtain();
174 final HistoryItem mHistoryLastWritten = new HistoryItem();
175 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700176 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700177 int mHistoryBufferLastPos = -1;
178 boolean mHistoryOverflow = false;
179 long mLastHistoryTime = 0;
180
181 final HistoryItem mHistoryCur = new HistoryItem();
182
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700183 HistoryItem mHistory;
184 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700185 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700186 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700187
188 private HistoryItem mHistoryIterator;
189 private boolean mReadOverflow;
190 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 int mStartCount;
193
194 long mBatteryUptime;
195 long mBatteryLastUptime;
196 long mBatteryRealtime;
197 long mBatteryLastRealtime;
198
199 long mUptime;
200 long mUptimeStart;
201 long mLastUptime;
202 long mRealtime;
203 long mRealtimeStart;
204 long mLastRealtime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700207 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700208
Dianne Hackborn617f8772009-03-31 15:04:46 -0700209 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700210 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700211
Dianne Hackborn617f8772009-03-31 15:04:46 -0700212 Counter mInputEventCounter;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700215 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700216
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700217 boolean mAudioOn;
218 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700219
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700220 boolean mVideoOn;
221 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700222
Dianne Hackborn627bba72009-03-24 22:32:56 -0700223 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800224 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700225 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800226 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700227
228 StopwatchTimer mPhoneSignalScanningTimer;
229
Dianne Hackborn627bba72009-03-24 22:32:56 -0700230 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700231 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700232 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700233
The Android Open Source Project10592532009-03-18 17:39:46 -0700234 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700235 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700236 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700237
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700238 boolean mGlobalWifiRunning;
239 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700240
The Android Open Source Project10592532009-03-18 17:39:46 -0700241 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700242 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700243
244 /** Bluetooth headset object */
245 BluetoothHeadset mBtHeadset;
246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 /**
248 * These provide time bases that discount the time the device is plugged
249 * in to power.
250 */
251 boolean mOnBattery;
252 boolean mOnBatteryInternal;
253 long mTrackBatteryPastUptime;
254 long mTrackBatteryUptimeStart;
255 long mTrackBatteryPastRealtime;
256 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 long mUnpluggedBatteryUptime;
259 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700260
The Android Open Source Project10592532009-03-18 17:39:46 -0700261 /*
262 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
263 */
Evan Millar633a1742009-04-02 16:36:33 -0700264 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700265 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700266 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700267 int mLowDischargeAmountSinceCharge;
268 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800269 int mDischargeScreenOnUnplugLevel;
270 int mDischargeScreenOffUnplugLevel;
271 int mDischargeAmountScreenOn;
272 int mDischargeAmountScreenOnSinceCharge;
273 int mDischargeAmountScreenOff;
274 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700277
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700278 // Mobile data transferred while on battery
279 private long[] mMobileDataTx = new long[4];
280 private long[] mMobileDataRx = new long[4];
281 private long[] mTotalDataTx = new long[4];
282 private long[] mTotalDataRx = new long[4];
283
284 private long mRadioDataUptime;
285 private long mRadioDataStart;
286
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700287 private int mBluetoothPingCount;
288 private int mBluetoothPingStart = -1;
289
Amith Yamasanif37447b2009-10-08 18:28:01 -0700290 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800291 private int mPhoneServiceStateRaw = -1;
292 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700293
Evan Millarc64edde2009-04-18 12:26:32 -0700294 /*
295 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
296 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700297 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700298 new HashMap<String, SamplingTimer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700299
Evan Millarc64edde2009-04-18 12:26:32 -0700300 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
301 return mKernelWakelockStats;
302 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700303
Evan Millarc64edde2009-04-18 12:26:32 -0700304 private static int sKernelWakelockUpdateVersion = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700305
Evan Millarc64edde2009-04-18 12:26:32 -0700306 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
307 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
308 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
309 Process.PROC_TAB_TERM,
310 Process.PROC_TAB_TERM,
311 Process.PROC_TAB_TERM,
312 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
313 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700314
Todd Poynor73f534a2012-06-19 11:07:26 -0700315 private static final int[] WAKEUP_SOURCES_FORMAT = new int[] {
316 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
317 Process.PROC_TAB_TERM|Process.PROC_COMBINE|
318 Process.PROC_OUT_LONG, // 1: count
319 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
320 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
321 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
322 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
323 Process.PROC_TAB_TERM|Process.PROC_COMBINE
324 |Process.PROC_OUT_LONG, // 6: totalTime
325 };
326
Evan Millarc64edde2009-04-18 12:26:32 -0700327 private final String[] mProcWakelocksName = new String[3];
328 private final long[] mProcWakelocksData = new long[3];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700329
Evan Millarc64edde2009-04-18 12:26:32 -0700330 /*
331 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
332 * to mKernelWakelockStats.
333 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700334 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700335 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700337 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700338
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700339 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
340
341 /** Network ifaces that {@link ConnectivityManager} has claimed as mobile. */
342 private HashSet<String> mMobileIfaces = Sets.newHashSet();
343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 // For debugging
345 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700346 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700347 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 }
349
350 public static interface Unpluggable {
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800351 void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime);
352 void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700356 * State for keeping track of counting information.
357 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700358 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700359 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700360 final ArrayList<Unpluggable> mUnpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700361 int mLoadedCount;
362 int mLastCount;
363 int mUnpluggedCount;
364 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700365
Dianne Hackborn617f8772009-03-31 15:04:46 -0700366 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700367 mUnpluggables = unpluggables;
Christopher Tate4cee7252010-03-19 14:50:40 -0700368 mPluggedCount = in.readInt();
369 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700370 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700371 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700372 mUnpluggedCount = in.readInt();
373 unpluggables.add(this);
374 }
375
376 Counter(ArrayList<Unpluggable> unpluggables) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700377 mUnpluggables = unpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700378 unpluggables.add(this);
379 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700380
Dianne Hackborn617f8772009-03-31 15:04:46 -0700381 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700382 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700383 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700384 out.writeInt(mUnpluggedCount);
385 }
386
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800387 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700388 mUnpluggedCount = mPluggedCount;
389 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700390 }
391
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800392 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700393 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700394 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700395
Dianne Hackborn617f8772009-03-31 15:04:46 -0700396 /**
397 * Writes a possibly null Counter to a Parcel.
398 *
399 * @param out the Parcel to be written to.
400 * @param counter a Counter, or null.
401 */
402 public static void writeCounterToParcel(Parcel out, Counter counter) {
403 if (counter == null) {
404 out.writeInt(0); // indicates null
405 return;
406 }
407 out.writeInt(1); // indicates non-null
408
409 counter.writeToParcel(out);
410 }
411
412 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700413 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700414 int val;
415 if (which == STATS_LAST) {
416 val = mLastCount;
417 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700418 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700419 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700420 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700421 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700422 val -= mLoadedCount;
423 }
424 }
425
426 return val;
427 }
428
429 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700430 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700431 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
432 + " mUnpluggedCount=" + mUnpluggedCount
433 + " mPluggedCount=" + mPluggedCount);
434 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700435
Christopher Tate4cee7252010-03-19 14:50:40 -0700436 void stepAtomic() {
437 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700438 }
439
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700440 /**
441 * Clear state of this counter.
442 */
443 void reset(boolean detachIfReset) {
444 mCount.set(0);
445 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
446 if (detachIfReset) {
447 detach();
448 }
449 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700450
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700451 void detach() {
452 mUnpluggables.remove(this);
453 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700454
Dianne Hackborn617f8772009-03-31 15:04:46 -0700455 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700456 int count = mCount.get();
457 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700458 }
459
460 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700461 mLoadedCount = in.readInt();
462 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700463 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700464 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700465 }
466 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700467
468 public static class SamplingCounter extends Counter {
469
470 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
471 super(unpluggables, in);
472 }
473
474 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
475 super(unpluggables);
476 }
477
Christopher Tate4cee7252010-03-19 14:50:40 -0700478 public void addCountAtomic(long count) {
479 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700480 }
481 }
482
Dianne Hackborn617f8772009-03-31 15:04:46 -0700483 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 * State for keeping track of timing information.
485 */
Evan Millarc64edde2009-04-18 12:26:32 -0700486 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 final int mType;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700488 final ArrayList<Unpluggable> mUnpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 int mCount;
491 int mLoadedCount;
492 int mLastCount;
493 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 // Times are in microseconds for better accuracy when dividing by the
496 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 /**
499 * The total time we have accumulated since the start of the original
500 * boot, to the last time something interesting happened in the
501 * current run.
502 */
503 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 /**
506 * The total time we loaded for the previous runs. Subtract this from
507 * mTotalTime to find the time for the current run of the system.
508 */
509 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 /**
512 * The run time of the last run of the system, as loaded from the
513 * saved data.
514 */
515 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 /**
518 * The value of mTotalTime when unplug() was last called. Subtract
519 * this from mTotalTime to find the time since the last unplug from
520 * power.
521 */
522 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700523
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700524 /**
525 * Constructs from a parcel.
526 * @param type
527 * @param unpluggables
528 * @param powerType
529 * @param in
530 */
Evan Millarc64edde2009-04-18 12:26:32 -0700531 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700533 mUnpluggables = unpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 mCount = in.readInt();
536 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700537 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 mUnpluggedCount = in.readInt();
539 mTotalTime = in.readLong();
540 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700541 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 mUnpluggedTime = in.readLong();
543 unpluggables.add(this);
544 }
545
Evan Millarc64edde2009-04-18 12:26:32 -0700546 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700548 mUnpluggables = unpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 unpluggables.add(this);
550 }
Evan Millarc64edde2009-04-18 12:26:32 -0700551
552 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700553
Evan Millarc64edde2009-04-18 12:26:32 -0700554 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700555
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700556 /**
557 * Clear state of this timer. Returns true if the timer is inactive
558 * so can be completely dropped.
559 */
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700560 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700561 mTotalTime = mLoadedTime = mLastTime = 0;
562 mCount = mLoadedCount = mLastCount = 0;
563 if (detachIfReset) {
564 detach();
565 }
566 return true;
567 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700568
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700569 void detach() {
570 mUnpluggables.remove(this);
571 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573 public void writeToParcel(Parcel out, long batteryRealtime) {
574 out.writeInt(mCount);
575 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 out.writeInt(mUnpluggedCount);
577 out.writeLong(computeRunTimeLocked(batteryRealtime));
578 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 out.writeLong(mUnpluggedTime);
580 }
581
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800582 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 if (DEBUG && mType < 0) {
584 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
585 + " old mUnpluggedTime=" + mUnpluggedTime
586 + " old mUnpluggedCount=" + mUnpluggedCount);
587 }
588 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
589 mUnpluggedCount = mCount;
590 if (DEBUG && mType < 0) {
591 Log.v(TAG, "unplug #" + mType
592 + ": new mUnpluggedTime=" + mUnpluggedTime
593 + " new mUnpluggedCount=" + mUnpluggedCount);
594 }
595 }
596
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800597 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700598 if (DEBUG && mType < 0) {
599 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
600 + " old mTotalTime=" + mTotalTime);
601 }
602 mTotalTime = computeRunTimeLocked(batteryRealtime);
603 mCount = computeCurrentCountLocked();
604 if (DEBUG && mType < 0) {
605 Log.v(TAG, "plug #" + mType
606 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 }
608 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 /**
611 * Writes a possibly null Timer to a Parcel.
612 *
613 * @param out the Parcel to be written to.
614 * @param timer a Timer, or null.
615 */
616 public static void writeTimerToParcel(Parcel out, Timer timer,
617 long batteryRealtime) {
618 if (timer == null) {
619 out.writeInt(0); // indicates null
620 return;
621 }
622 out.writeInt(1); // indicates non-null
623
624 timer.writeToParcel(out, batteryRealtime);
625 }
626
627 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700628 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 long val;
630 if (which == STATS_LAST) {
631 val = mLastTime;
632 } else {
633 val = computeRunTimeLocked(batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700634 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 val -= mUnpluggedTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700636 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 val -= mLoadedTime;
638 }
639 }
640
641 return val;
642 }
643
644 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700645 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800646 int val;
647 if (which == STATS_LAST) {
648 val = mLastCount;
649 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700650 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700651 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700653 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 val -= mLoadedCount;
655 }
656 }
657
658 return val;
659 }
660
Dianne Hackborn627bba72009-03-24 22:32:56 -0700661 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700662 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
664 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700665 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800666 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700667 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700669 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700670
671
Evan Millarc64edde2009-04-18 12:26:32 -0700672 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
673 long runTime = computeRunTimeLocked(batteryRealtime);
674 // Divide by 1000 for backwards compatibility
675 out.writeLong((runTime + 500) / 1000);
Evan Millarc64edde2009-04-18 12:26:32 -0700676 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -0700677 }
678
679 void readSummaryFromParcelLocked(Parcel in) {
680 // Multiply by 1000 for backwards compatibility
681 mTotalTime = mLoadedTime = in.readLong() * 1000;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700682 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700683 mUnpluggedTime = mTotalTime;
684 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700685 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700686 mUnpluggedCount = mCount;
687 }
688 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700689
Evan Millarc64edde2009-04-18 12:26:32 -0700690 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700691
Evan Millarc64edde2009-04-18 12:26:32 -0700692 /**
693 * The most recent reported count from /proc/wakelocks.
694 */
695 int mCurrentReportedCount;
696
697 /**
698 * The reported count from /proc/wakelocks when unplug() was last
699 * called.
700 */
701 int mUnpluggedReportedCount;
702
703 /**
704 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700705 */
Evan Millarc64edde2009-04-18 12:26:32 -0700706 long mCurrentReportedTotalTime;
707
708
709 /**
710 * The reported total_time from /proc/wakelocks when unplug() was last
711 * called.
712 */
713 long mUnpluggedReportedTotalTime;
714
715 /**
716 * Whether we are currently in a discharge cycle.
717 */
718 boolean mInDischarge;
719
720 /**
721 * Whether we are currently recording reported values.
722 */
723 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700724
Evan Millarc64edde2009-04-18 12:26:32 -0700725 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800726 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -0700727 */
728 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700729
Evan Millarc64edde2009-04-18 12:26:32 -0700730 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
731 super(0, unpluggables, in);
732 mCurrentReportedCount = in.readInt();
733 mUnpluggedReportedCount = in.readInt();
734 mCurrentReportedTotalTime = in.readLong();
735 mUnpluggedReportedTotalTime = in.readLong();
736 mTrackingReportedValues = in.readInt() == 1;
737 mInDischarge = inDischarge;
738 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700739
740 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
Evan Millarc64edde2009-04-18 12:26:32 -0700741 boolean trackReportedValues) {
742 super(0, unpluggables);
743 mTrackingReportedValues = trackReportedValues;
744 mInDischarge = inDischarge;
745 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700746
Evan Millarc64edde2009-04-18 12:26:32 -0700747 public void setStale() {
748 mTrackingReportedValues = false;
749 mUnpluggedReportedTotalTime = 0;
750 mUnpluggedReportedCount = 0;
751 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700752
Evan Millarc64edde2009-04-18 12:26:32 -0700753 public void setUpdateVersion(int version) {
754 mUpdateVersion = version;
755 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700756
Evan Millarc64edde2009-04-18 12:26:32 -0700757 public int getUpdateVersion() {
758 return mUpdateVersion;
759 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700760
Evan Millarc64edde2009-04-18 12:26:32 -0700761 public void updateCurrentReportedCount(int count) {
762 if (mInDischarge && mUnpluggedReportedCount == 0) {
763 // Updating the reported value for the first time.
764 mUnpluggedReportedCount = count;
765 // If we are receiving an update update mTrackingReportedValues;
766 mTrackingReportedValues = true;
767 }
768 mCurrentReportedCount = count;
769 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700770
Evan Millarc64edde2009-04-18 12:26:32 -0700771 public void updateCurrentReportedTotalTime(long totalTime) {
772 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
773 // Updating the reported value for the first time.
774 mUnpluggedReportedTotalTime = totalTime;
775 // If we are receiving an update update mTrackingReportedValues;
776 mTrackingReportedValues = true;
777 }
778 mCurrentReportedTotalTime = totalTime;
779 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700780
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800781 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
782 super.unplug(elapsedRealtime, batteryUptime, batteryRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -0700783 if (mTrackingReportedValues) {
784 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
785 mUnpluggedReportedCount = mCurrentReportedCount;
786 }
787 mInDischarge = true;
788 }
789
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800790 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
791 super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -0700792 mInDischarge = false;
793 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700794
Evan Millarc64edde2009-04-18 12:26:32 -0700795 public void logState(Printer pw, String prefix) {
796 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700797 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -0700798 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
799 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
800 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
801 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700802
Evan Millarc64edde2009-04-18 12:26:32 -0700803 protected long computeRunTimeLocked(long curBatteryRealtime) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700804 return mTotalTime + (mInDischarge && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -0700805 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
806 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700807
Evan Millarc64edde2009-04-18 12:26:32 -0700808 protected int computeCurrentCountLocked() {
809 return mCount + (mInDischarge && mTrackingReportedValues
810 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
811 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700812
Evan Millarc64edde2009-04-18 12:26:32 -0700813 public void writeToParcel(Parcel out, long batteryRealtime) {
814 super.writeToParcel(out, batteryRealtime);
815 out.writeInt(mCurrentReportedCount);
816 out.writeInt(mUnpluggedReportedCount);
817 out.writeLong(mCurrentReportedTotalTime);
818 out.writeLong(mUnpluggedReportedTotalTime);
819 out.writeInt(mTrackingReportedValues ? 1 : 0);
820 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700821
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700822 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
823 super.reset(stats, detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700824 setStale();
825 return true;
826 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700827
Evan Millarc64edde2009-04-18 12:26:32 -0700828 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
829 super.writeSummaryFromParcelLocked(out, batteryRealtime);
830 out.writeLong(mCurrentReportedTotalTime);
831 out.writeInt(mCurrentReportedCount);
832 out.writeInt(mTrackingReportedValues ? 1 : 0);
833 }
834
835 void readSummaryFromParcelLocked(Parcel in) {
836 super.readSummaryFromParcelLocked(in);
837 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
838 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
839 mTrackingReportedValues = in.readInt() == 1;
840 }
841 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700842
Evan Millarc64edde2009-04-18 12:26:32 -0700843 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800844 * A timer that increments in batches. It does not run for durations, but just jumps
845 * for a pre-determined amount.
846 */
847 public static final class BatchTimer extends Timer {
848 final Uid mUid;
849
850 /**
851 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
852 */
853 long mLastAddedTime;
854
855 /**
856 * The last duration that we added to the timer. This is in microseconds.
857 */
858 long mLastAddedDuration;
859
860 /**
861 * Whether we are currently in a discharge cycle.
862 */
863 boolean mInDischarge;
864
865 BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables,
866 boolean inDischarge, Parcel in) {
867 super(type, unpluggables, in);
868 mUid = uid;
869 mLastAddedTime = in.readLong();
870 mLastAddedDuration = in.readLong();
871 mInDischarge = inDischarge;
872 }
873
874 BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables,
875 boolean inDischarge) {
876 super(type, unpluggables);
877 mUid = uid;
878 mInDischarge = inDischarge;
879 }
880
881 @Override
882 public void writeToParcel(Parcel out, long batteryRealtime) {
883 super.writeToParcel(out, batteryRealtime);
884 out.writeLong(mLastAddedTime);
885 out.writeLong(mLastAddedDuration);
886 }
887
888 @Override
889 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
890 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
891 mInDischarge = false;
892 super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
893 }
894
895 @Override
896 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
897 recomputeLastDuration(elapsedRealtime, false);
898 mInDischarge = true;
899 // If we are still within the last added duration, then re-added whatever remains.
900 if (mLastAddedTime == elapsedRealtime) {
901 mTotalTime += mLastAddedDuration;
902 }
903 super.unplug(elapsedRealtime, batteryUptime, batteryRealtime);
904 }
905
906 @Override
907 public void logState(Printer pw, String prefix) {
908 super.logState(pw, prefix);
909 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
910 + " mLastAddedDuration=" + mLastAddedDuration);
911 }
912
913 private long computeOverage(long curTime) {
914 if (mLastAddedTime > 0) {
915 return mLastTime + mLastAddedDuration - curTime;
916 }
917 return 0;
918 }
919
920 private void recomputeLastDuration(long curTime, boolean abort) {
921 final long overage = computeOverage(curTime);
922 if (overage > 0) {
923 // Aborting before the duration ran out -- roll back the remaining
924 // duration. Only do this if currently discharging; otherwise we didn't
925 // actually add the time.
926 if (mInDischarge) {
927 mTotalTime -= overage;
928 }
929 if (abort) {
930 mLastAddedTime = 0;
931 } else {
932 mLastAddedTime = curTime;
933 mLastAddedDuration -= overage;
934 }
935 }
936 }
937
938 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
939 final long now = SystemClock.elapsedRealtime() * 1000;
940 recomputeLastDuration(now, true);
941 mLastAddedTime = now;
942 mLastAddedDuration = durationMillis * 1000;
943 if (mInDischarge) {
944 mTotalTime += mLastAddedDuration;
945 mCount++;
946 }
947 }
948
949 public void abortLastDuration(BatteryStatsImpl stats) {
950 final long now = SystemClock.elapsedRealtime() * 1000;
951 recomputeLastDuration(now, true);
952 }
953
954 @Override
955 protected int computeCurrentCountLocked() {
956 return mCount;
957 }
958
959 @Override
960 protected long computeRunTimeLocked(long curBatteryRealtime) {
961 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000);
962 if (overage > 0) {
963 return mTotalTime = overage;
964 }
965 return mTotalTime;
966 }
967
968 @Override
969 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
970 final long now = SystemClock.elapsedRealtime() * 1000;
971 recomputeLastDuration(now, true);
972 boolean stillActive = mLastAddedTime == now;
973 super.reset(stats, !stillActive && detachIfReset);
974 return !stillActive;
975 }
976 }
977
978 /**
Evan Millarc64edde2009-04-18 12:26:32 -0700979 * State for keeping track of timing information.
980 */
981 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700982 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -0700983 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700984
Evan Millarc64edde2009-04-18 12:26:32 -0700985 int mNesting;
986
Evan Millarc64edde2009-04-18 12:26:32 -0700987 /**
988 * The last time at which we updated the timer. If mNesting is > 0,
989 * subtract this from the current battery time to find the amount of
990 * time we have been running since we last computed an update.
991 */
992 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700993
Evan Millarc64edde2009-04-18 12:26:32 -0700994 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700995 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -0700996 * was actually held for an interesting duration.
997 */
998 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700999
Amith Yamasanif37447b2009-10-08 18:28:01 -07001000 long mTimeout;
1001
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001002 /**
1003 * For partial wake locks, keep track of whether we are in the list
1004 * to consume CPU cycles.
1005 */
1006 boolean mInList;
1007
1008 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -07001009 ArrayList<Unpluggable> unpluggables, Parcel in) {
1010 super(type, unpluggables, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001011 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001012 mTimerPool = timerPool;
1013 mUpdateTime = in.readLong();
1014 }
1015
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001016 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -07001017 ArrayList<Unpluggable> unpluggables) {
1018 super(type, unpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001019 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001020 mTimerPool = timerPool;
1021 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001022
Amith Yamasanif37447b2009-10-08 18:28:01 -07001023 void setTimeout(long timeout) {
1024 mTimeout = timeout;
1025 }
1026
Evan Millarc64edde2009-04-18 12:26:32 -07001027 public void writeToParcel(Parcel out, long batteryRealtime) {
1028 super.writeToParcel(out, batteryRealtime);
1029 out.writeLong(mUpdateTime);
1030 }
1031
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001032 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001033 if (mNesting > 0) {
1034 if (DEBUG && mType < 0) {
1035 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
1036 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001037 super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001038 mUpdateTime = batteryRealtime;
1039 if (DEBUG && mType < 0) {
1040 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
1041 }
1042 }
1043 }
1044
1045 public void logState(Printer pw, String prefix) {
1046 super.logState(pw, prefix);
1047 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 + " mAcquireTime=" + mAcquireTime);
1049 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001051 void startRunningLocked(BatteryStatsImpl stats) {
1052 if (mNesting++ == 0) {
1053 mUpdateTime = stats.getBatteryRealtimeLocked(
1054 SystemClock.elapsedRealtime() * 1000);
1055 if (mTimerPool != null) {
1056 // Accumulate time to all currently active timers before adding
1057 // this new one to the pool.
1058 refreshTimersLocked(stats, mTimerPool);
1059 // Add this timer to the active pool
1060 mTimerPool.add(this);
1061 }
1062 // Increment the count
1063 mCount++;
1064 mAcquireTime = mTotalTime;
1065 if (DEBUG && mType < 0) {
1066 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
1067 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1068 + " mAcquireTime=" + mAcquireTime);
1069 }
1070 }
1071 }
1072
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001073 boolean isRunningLocked() {
1074 return mNesting > 0;
1075 }
1076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 void stopRunningLocked(BatteryStatsImpl stats) {
1078 // Ignore attempt to stop a timer that isn't running
1079 if (mNesting == 0) {
1080 return;
1081 }
1082 if (--mNesting == 0) {
1083 if (mTimerPool != null) {
1084 // Accumulate time to all active counters, scaled by the total
1085 // active in the pool, before taking this one out of the pool.
1086 refreshTimersLocked(stats, mTimerPool);
1087 // Remove this timer from the active pool
1088 mTimerPool.remove(this);
1089 } else {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001090 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001091 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
1092 mNesting = 1;
1093 mTotalTime = computeRunTimeLocked(batteryRealtime);
1094 mNesting = 0;
1095 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001097 if (DEBUG && mType < 0) {
1098 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
1099 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1100 + " mAcquireTime=" + mAcquireTime);
1101 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 if (mTotalTime == mAcquireTime) {
1104 // If there was no change in the time, then discard this
1105 // count. A somewhat cheezy strategy, but hey.
1106 mCount--;
1107 }
1108 }
1109 }
1110
1111 // Update the total time for all other running Timers with the same type as this Timer
1112 // due to a change in timer count
1113 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -07001114 final ArrayList<StopwatchTimer> pool) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001115 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
1117 final int N = pool.size();
1118 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07001119 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 long heldTime = batteryRealtime - t.mUpdateTime;
1121 if (heldTime > 0) {
1122 t.mTotalTime += heldTime / N;
1123 }
1124 t.mUpdateTime = batteryRealtime;
1125 }
1126 }
1127
Evan Millarc64edde2009-04-18 12:26:32 -07001128 @Override
1129 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001130 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
1131 curBatteryRealtime = mUpdateTime + mTimeout;
1132 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133 return mTotalTime + (mNesting > 0
1134 ? (curBatteryRealtime - mUpdateTime)
1135 / (mTimerPool != null ? mTimerPool.size() : 1)
1136 : 0);
1137 }
1138
Evan Millarc64edde2009-04-18 12:26:32 -07001139 @Override
1140 protected int computeCurrentCountLocked() {
1141 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 }
1143
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001144 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001145 boolean canDetach = mNesting <= 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001146 super.reset(stats, canDetach && detachIfReset);
1147 if (mNesting > 0) {
1148 mUpdateTime = stats.getBatteryRealtimeLocked(
1149 SystemClock.elapsedRealtime() * 1000);
1150 }
1151 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001152 return canDetach;
1153 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001154
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001155 void detach() {
1156 super.detach();
1157 if (mTimerPool != null) {
1158 mTimerPool.remove(this);
1159 }
1160 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001163 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001164 mNesting = 0;
1165 }
1166 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001167
Evan Millarc64edde2009-04-18 12:26:32 -07001168 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001169
Todd Poynor73f534a2012-06-19 11:07:26 -07001170 FileInputStream is;
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001171 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -07001172 int len;
Todd Poynor73f534a2012-06-19 11:07:26 -07001173 boolean wakeup_sources = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001174
Evan Millarc64edde2009-04-18 12:26:32 -07001175 try {
Todd Poynor73f534a2012-06-19 11:07:26 -07001176 try {
1177 is = new FileInputStream("/proc/wakelocks");
1178 } catch (java.io.FileNotFoundException e) {
1179 try {
1180 is = new FileInputStream("/d/wakeup_sources");
1181 wakeup_sources = true;
1182 } catch (java.io.FileNotFoundException e2) {
1183 return null;
Evan Millarc64edde2009-04-18 12:26:32 -07001184 }
1185 }
Todd Poynor73f534a2012-06-19 11:07:26 -07001186
1187 len = is.read(buffer);
1188 is.close();
Evan Millarc64edde2009-04-18 12:26:32 -07001189 } catch (java.io.IOException e) {
1190 return null;
1191 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001192
Todd Poynor73f534a2012-06-19 11:07:26 -07001193 if (len > 0) {
1194 int i;
1195 for (i=0; i<len; i++) {
1196 if (buffer[i] == '\0') {
1197 len = i;
1198 break;
1199 }
1200 }
1201 }
1202
1203 return parseProcWakelocks(buffer, len, wakeup_sources);
Evan Millarc64edde2009-04-18 12:26:32 -07001204 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001205
Evan Millarc64edde2009-04-18 12:26:32 -07001206 private final Map<String, KernelWakelockStats> parseProcWakelocks(
Todd Poynor73f534a2012-06-19 11:07:26 -07001207 byte[] wlBuffer, int len, boolean wakeup_sources) {
Evan Millarc64edde2009-04-18 12:26:32 -07001208 String name;
1209 int count;
1210 long totalTime;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001211 int startIndex;
1212 int endIndex;
Evan Millarc64edde2009-04-18 12:26:32 -07001213 int numUpdatedWlNames = 0;
1214
1215 // Advance past the first line.
1216 int i;
1217 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1218 startIndex = endIndex = i + 1;
1219
1220 synchronized(this) {
1221 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001222
Evan Millarc64edde2009-04-18 12:26:32 -07001223 sKernelWakelockUpdateVersion++;
1224 while (endIndex < len) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001225 for (endIndex=startIndex;
1226 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
Evan Millarc64edde2009-04-18 12:26:32 -07001227 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001228 endIndex++; // endIndex is an exclusive upper bound.
1229 // Don't go over the end of the buffer, Process.parseProcLine might
1230 // write to wlBuffer[endIndex]
1231 if (endIndex >= (len - 1) ) {
1232 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -07001233 }
Evan Millarc64edde2009-04-18 12:26:32 -07001234
1235 String[] nameStringArray = mProcWakelocksName;
1236 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001237 // Stomp out any bad characters since this is from a circular buffer
1238 // A corruption is seen sometimes that results in the vm crashing
1239 // This should prevent crashes and the line will probably fail to parse
1240 for (int j = startIndex; j < endIndex; j++) {
1241 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1242 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001243 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
Todd Poynor73f534a2012-06-19 11:07:26 -07001244 wakeup_sources ? WAKEUP_SOURCES_FORMAT :
1245 PROC_WAKELOCKS_FORMAT,
1246 nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001247
Evan Millarc64edde2009-04-18 12:26:32 -07001248 name = nameStringArray[0];
1249 count = (int) wlData[1];
Todd Poynor73f534a2012-06-19 11:07:26 -07001250
1251 if (wakeup_sources) {
1252 // convert milliseconds to microseconds
1253 totalTime = wlData[2] * 1000;
1254 } else {
1255 // convert nanoseconds to microseconds with rounding.
1256 totalTime = (wlData[2] + 500) / 1000;
1257 }
Evan Millarc64edde2009-04-18 12:26:32 -07001258
Amith Yamasani53b707b2009-09-30 11:05:30 -07001259 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001260 if (!m.containsKey(name)) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001261 m.put(name, new KernelWakelockStats(count, totalTime,
Evan Millarc64edde2009-04-18 12:26:32 -07001262 sKernelWakelockUpdateVersion));
1263 numUpdatedWlNames++;
1264 } else {
1265 KernelWakelockStats kwlStats = m.get(name);
1266 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1267 kwlStats.mCount += count;
1268 kwlStats.mTotalTime += totalTime;
1269 } else {
1270 kwlStats.mCount = count;
1271 kwlStats.mTotalTime = totalTime;
1272 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1273 numUpdatedWlNames++;
1274 }
1275 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001276 }
Evan Millarc64edde2009-04-18 12:26:32 -07001277 startIndex = endIndex;
1278 }
1279
1280 if (m.size() != numUpdatedWlNames) {
1281 // Don't report old data.
1282 Iterator<KernelWakelockStats> itr = m.values().iterator();
1283 while (itr.hasNext()) {
1284 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1285 itr.remove();
1286 }
1287 }
1288 }
1289 return m;
1290 }
1291 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001292
Evan Millarc64edde2009-04-18 12:26:32 -07001293 private class KernelWakelockStats {
1294 public int mCount;
1295 public long mTotalTime;
1296 public int mVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001297
Evan Millarc64edde2009-04-18 12:26:32 -07001298 KernelWakelockStats(int count, long totalTime, int version) {
1299 mCount = count;
1300 mTotalTime = totalTime;
1301 mVersion = version;
1302 }
1303 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001304
Evan Millarc64edde2009-04-18 12:26:32 -07001305 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001306 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001307 * doesn't already exist.
1308 */
1309 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1310 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1311 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001312 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07001313 true /* track reported values */);
1314 mKernelWakelockStats.put(name, kwlt);
1315 }
1316 return kwlt;
1317 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001318
1319 private void doDataPlug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001320 dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED];
1321 dataTransfer[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001322 }
1323
1324 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001325 dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001326 }
1327
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001328 /**
1329 * Radio uptime in microseconds when transferring data. This value is very approximate.
1330 * @return
1331 */
1332 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001333 try {
1334 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
1335 if (!awakeTimeFile.exists()) return 0;
1336 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
1337 String line = br.readLine();
1338 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001339 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001340 } catch (NumberFormatException nfe) {
1341 // Nothing
1342 } catch (IOException ioe) {
1343 // Nothing
1344 }
1345 return 0;
1346 }
1347
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001348 /**
1349 * @deprecated use getRadioDataUptime
1350 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001351 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001352 return getRadioDataUptime() / 1000;
1353 }
1354
1355 /**
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001356 * Returns the duration that the cell radio was up for data transfers.
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001357 */
1358 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001359 if (mRadioDataStart == -1) {
1360 return mRadioDataUptime;
1361 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001362 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001363 }
1364 }
1365
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001366 private int getCurrentBluetoothPingCount() {
1367 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001368 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1369 if (deviceList.size() > 0) {
1370 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001371 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001372 }
1373 return -1;
1374 }
1375
1376 public int getBluetoothPingCount() {
1377 if (mBluetoothPingStart == -1) {
1378 return mBluetoothPingCount;
1379 } else if (mBtHeadset != null) {
1380 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1381 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001382 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001383 }
1384
1385 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001386 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1387 mBluetoothPingStart = getCurrentBluetoothPingCount();
1388 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001389 mBtHeadset = headset;
1390 }
1391
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001392 int mChangedBufferStates = 0;
1393
1394 void addHistoryBufferLocked(long curTime) {
1395 if (!mHaveBatteryLevel || !mRecordingHistory) {
1396 return;
1397 }
1398
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001399 final long timeDiff = (mHistoryBaseTime+curTime) - mHistoryLastWritten.time;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001400 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001401 && timeDiff < 2000
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001402 && ((mHistoryLastWritten.states^mHistoryCur.states)&mChangedBufferStates) == 0) {
1403 // If the current is the same as the one before, then we no
1404 // longer need the entry.
1405 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
1406 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
1407 mHistoryBufferLastPos = -1;
1408 if (mHistoryLastLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001409 && timeDiff < 500 && mHistoryLastLastWritten.same(mHistoryCur)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001410 // If this results in us returning to the state written
1411 // prior to the last one, then we can just delete the last
1412 // written one and drop the new one. Nothing more to do.
1413 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
1414 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1415 return;
1416 }
1417 mChangedBufferStates |= mHistoryLastWritten.states^mHistoryCur.states;
1418 curTime = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001419 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001420 } else {
1421 mChangedBufferStates = 0;
1422 }
1423
1424 final int dataSize = mHistoryBuffer.dataSize();
1425 if (dataSize >= MAX_HISTORY_BUFFER) {
1426 if (!mHistoryOverflow) {
1427 mHistoryOverflow = true;
1428 addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW);
1429 }
1430
1431 // Once we've reached the maximum number of items, we only
1432 // record changes to the battery level and the most interesting states.
1433 // Once we've reached the maximum maximum number of items, we only
1434 // record changes to the battery level.
1435 if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
1436 (dataSize >= MAX_MAX_HISTORY_BUFFER
Amith Yamasani45f06462011-11-21 16:08:34 -08001437 || ((mHistoryLastWritten.states^mHistoryCur.states)
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001438 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
1439 return;
1440 }
1441 }
1442
1443 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE);
1444 }
1445
1446 void addHistoryBufferLocked(long curTime, byte cmd) {
1447 int origPos = 0;
1448 if (mIteratingHistory) {
1449 origPos = mHistoryBuffer.dataPosition();
1450 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
1451 }
1452 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
1453 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
1454 mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
1455 mHistoryLastWritten.writeDelta(mHistoryBuffer, mHistoryLastLastWritten);
1456 mLastHistoryTime = curTime;
1457 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
1458 + " now " + mHistoryBuffer.dataPosition()
1459 + " size is now " + mHistoryBuffer.dataSize());
1460 if (mIteratingHistory) {
1461 mHistoryBuffer.setDataPosition(origPos);
1462 }
1463 }
1464
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001465 int mChangedStates = 0;
1466
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001467 void addHistoryRecordLocked(long curTime) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001468 addHistoryBufferLocked(curTime);
1469
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001470 if (!USE_OLD_HISTORY) {
1471 return;
1472 }
1473
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001474 if (!mHaveBatteryLevel || !mRecordingHistory) {
1475 return;
1476 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001477
1478 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001479 // and no states have since the last recorded entry changed and
1480 // are now resetting back to their original value, then just collapse
1481 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001482 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001483 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000)
1484 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001485 // If the current is the same as the one before, then we no
1486 // longer need the entry.
1487 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001488 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500)
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001489 && mHistoryLastEnd.same(mHistoryCur)) {
1490 mHistoryLastEnd.next = null;
1491 mHistoryEnd.next = mHistoryCache;
1492 mHistoryCache = mHistoryEnd;
1493 mHistoryEnd = mHistoryLastEnd;
1494 mHistoryLastEnd = null;
1495 } else {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001496 mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001497 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
1498 }
1499 return;
1500 }
1501
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001502 mChangedStates = 0;
1503
1504 if (mNumHistoryItems == MAX_HISTORY_ITEMS
1505 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001506 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
1507 }
1508
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001509 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
1510 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001511 // record changes to the battery level and the most interesting states.
1512 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001513 // record changes to the battery level.
1514 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001515 == mHistoryCur.batteryLevel &&
1516 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
1517 || ((mHistoryEnd.states^mHistoryCur.states)
1518 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001519 return;
1520 }
1521 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001522
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001523 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
1524 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001525
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001526 void addHistoryRecordLocked(long curTime, byte cmd) {
1527 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001528 if (rec != null) {
1529 mHistoryCache = rec.next;
1530 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001531 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001532 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001533 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001534
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001535 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001536 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001537
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001538 void addHistoryRecordLocked(HistoryItem rec) {
1539 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001540 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001541 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001542 if (mHistoryEnd != null) {
1543 mHistoryEnd.next = rec;
1544 mHistoryEnd = rec;
1545 } else {
1546 mHistory = mHistoryEnd = rec;
1547 }
1548 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001549
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001550 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001551 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001552 if (USE_OLD_HISTORY) {
1553 if (mHistory != null) {
1554 mHistoryEnd.next = mHistoryCache;
1555 mHistoryCache = mHistory;
1556 mHistory = mHistoryLastEnd = mHistoryEnd = null;
1557 }
1558 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001559 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001560
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001561 mHistoryBaseTime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001562 mLastHistoryTime = 0;
1563
1564 mHistoryBuffer.setDataSize(0);
1565 mHistoryBuffer.setDataPosition(0);
1566 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER/2);
1567 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1568 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
1569 mHistoryBufferLastPos = -1;
1570 mHistoryOverflow = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001571 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001572
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001573 public void doUnplugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001574 NetworkStats.Entry entry = null;
1575
1576 // Track UID data usage
1577 final NetworkStats uidStats = getNetworkStatsDetailGroupedByUid();
1578 final int size = uidStats.size();
1579 for (int i = 0; i < size; i++) {
1580 entry = uidStats.getValues(i, entry);
1581
Jeff Sharkey51797ed2013-06-04 14:09:31 -07001582 final Uid u = getUidStatsLocked(entry.uid);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001583 u.mStartedTcpBytesReceived = entry.rxBytes;
1584 u.mStartedTcpBytesSent = entry.txBytes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1586 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1587 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001590 mUnpluggables.get(i).unplug(elapsedRealtime, batteryUptime, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001592
1593 // Track both mobile and total overall data
1594 final NetworkStats ifaceStats = getNetworkStatsSummary();
1595 entry = ifaceStats.getTotal(entry, mMobileIfaces);
1596 doDataUnplug(mMobileDataRx, entry.rxBytes);
1597 doDataUnplug(mMobileDataTx, entry.txBytes);
1598 entry = ifaceStats.getTotal(entry);
1599 doDataUnplug(mTotalDataRx, entry.rxBytes);
1600 doDataUnplug(mTotalDataTx, entry.txBytes);
1601
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001602 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001603 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001604 mRadioDataUptime = 0;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001605
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001606 // Track bt headset ping count
1607 mBluetoothPingStart = getCurrentBluetoothPingCount();
1608 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001610
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001611 public void doPlugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001612 NetworkStats.Entry entry = null;
1613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1615 Uid u = mUidStats.valueAt(iu);
1616 if (u.mStartedTcpBytesReceived >= 0) {
1617 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1618 u.mStartedTcpBytesReceived = -1;
1619 }
1620 if (u.mStartedTcpBytesSent >= 0) {
1621 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1622 u.mStartedTcpBytesSent = -1;
1623 }
1624 }
1625 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001626 mUnpluggables.get(i).plug(elapsedRealtime, batteryUptime, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001627 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001628
1629 // Track both mobile and total overall data
1630 final NetworkStats ifaceStats = getNetworkStatsSummary();
1631 entry = ifaceStats.getTotal(entry, mMobileIfaces);
1632 doDataPlug(mMobileDataRx, entry.rxBytes);
1633 doDataPlug(mMobileDataTx, entry.txBytes);
1634 entry = ifaceStats.getTotal(entry);
1635 doDataPlug(mTotalDataRx, entry.rxBytes);
1636 doDataPlug(mTotalDataTx, entry.txBytes);
1637
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001638 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001639 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001640 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001641
1642 // Track bt headset ping count
1643 mBluetoothPingCount = getBluetoothPingCount();
1644 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001646
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001647 int mWakeLockNesting;
1648
1649 public void noteStartWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001650 if (type == WAKE_TYPE_PARTIAL) {
1651 // Only care about partial wake locks, since full wake locks
1652 // will be canceled when the user puts the screen to sleep.
1653 if (mWakeLockNesting == 0) {
1654 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
1655 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
1656 + Integer.toHexString(mHistoryCur.states));
1657 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1658 }
1659 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001660 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001661 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001662 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1663 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1664 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1665 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001666 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
1667 }
1668 }
1669
1670 public void noteStopWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001671 if (type == WAKE_TYPE_PARTIAL) {
1672 mWakeLockNesting--;
1673 if (mWakeLockNesting == 0) {
1674 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
1675 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
1676 + Integer.toHexString(mHistoryCur.states));
1677 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1678 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001679 }
1680 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001681 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1682 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1683 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1684 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001685 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
1686 }
1687 }
1688
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001689 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1690 int N = ws.size();
1691 for (int i=0; i<N; i++) {
1692 noteStartWakeLocked(ws.get(i), pid, name, type);
1693 }
1694 }
1695
1696 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1697 int N = ws.size();
1698 for (int i=0; i<N; i++) {
1699 noteStopWakeLocked(ws.get(i), pid, name, type);
1700 }
1701 }
1702
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001703 public int startAddingCpuLocked() {
1704 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
1705
1706 if (mScreenOn) {
1707 return 0;
1708 }
1709
1710 final int N = mPartialTimers.size();
1711 if (N == 0) {
1712 mLastPartialTimers.clear();
1713 return 0;
1714 }
1715
1716 // How many timers should consume CPU? Only want to include ones
1717 // that have already been in the list.
1718 for (int i=0; i<N; i++) {
1719 StopwatchTimer st = mPartialTimers.get(i);
1720 if (st.mInList) {
1721 Uid uid = st.mUid;
1722 // We don't include the system UID, because it so often
1723 // holds wake locks at one request or another of an app.
1724 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1725 return 50;
1726 }
1727 }
1728 }
1729
1730 return 0;
1731 }
1732
1733 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
1734 final int N = mPartialTimers.size();
1735 if (perc != 0) {
1736 int num = 0;
1737 for (int i=0; i<N; i++) {
1738 StopwatchTimer st = mPartialTimers.get(i);
1739 if (st.mInList) {
1740 Uid uid = st.mUid;
1741 // We don't include the system UID, because it so often
1742 // holds wake locks at one request or another of an app.
1743 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1744 num++;
1745 }
1746 }
1747 }
1748 if (num != 0) {
1749 for (int i=0; i<N; i++) {
1750 StopwatchTimer st = mPartialTimers.get(i);
1751 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001752 Uid uid = st.mUid;
1753 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07001754 int myUTime = utime/num;
1755 int mySTime = stime/num;
1756 utime -= myUTime;
1757 stime -= mySTime;
1758 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001759 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
1760 proc.addCpuTimeLocked(myUTime, mySTime);
1761 proc.addSpeedStepTimes(cpuSpeedTimes);
1762 }
1763 }
1764 }
1765 }
1766
1767 // Just in case, collect any lost CPU time.
1768 if (utime != 0 || stime != 0) {
1769 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
1770 if (uid != null) {
1771 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
1772 proc.addCpuTimeLocked(utime, stime);
1773 proc.addSpeedStepTimes(cpuSpeedTimes);
1774 }
1775 }
1776 }
1777
1778 final int NL = mLastPartialTimers.size();
1779 boolean diff = N != NL;
1780 for (int i=0; i<NL && !diff; i++) {
1781 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
1782 }
1783 if (!diff) {
1784 for (int i=0; i<NL; i++) {
1785 mPartialTimers.get(i).mInList = true;
1786 }
1787 return;
1788 }
1789
1790 for (int i=0; i<NL; i++) {
1791 mLastPartialTimers.get(i).mInList = false;
1792 }
1793 mLastPartialTimers.clear();
1794 for (int i=0; i<N; i++) {
1795 StopwatchTimer st = mPartialTimers.get(i);
1796 st.mInList = true;
1797 mLastPartialTimers.add(st);
1798 }
1799 }
1800
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001801 public void noteProcessDiedLocked(int uid, int pid) {
1802 Uid u = mUidStats.get(uid);
1803 if (u != null) {
1804 u.mPids.remove(pid);
1805 }
1806 }
1807
1808 public long getProcessWakeTime(int uid, int pid, long realtime) {
1809 Uid u = mUidStats.get(uid);
1810 if (u != null) {
1811 Uid.Pid p = u.mPids.get(pid);
1812 if (p != null) {
1813 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
1814 }
1815 }
1816 return 0;
1817 }
1818
1819 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
1820 Uid u = mUidStats.get(uid);
1821 if (u != null) {
1822 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
1823 }
1824 }
1825
Dianne Hackborn287952c2010-09-22 22:34:31 -07001826 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
1827 Uid u = mUidStats.get(uid);
1828 if (u != null) {
1829 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
1830 }
1831 }
1832
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001833 int mSensorNesting;
1834
1835 public void noteStartSensorLocked(int uid, int sensor) {
1836 if (mSensorNesting == 0) {
1837 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
1838 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
1839 + Integer.toHexString(mHistoryCur.states));
1840 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1841 }
1842 mSensorNesting++;
1843 getUidStatsLocked(uid).noteStartSensor(sensor);
1844 }
1845
1846 public void noteStopSensorLocked(int uid, int sensor) {
1847 mSensorNesting--;
1848 if (mSensorNesting == 0) {
1849 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
1850 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
1851 + Integer.toHexString(mHistoryCur.states));
1852 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1853 }
1854 getUidStatsLocked(uid).noteStopSensor(sensor);
1855 }
1856
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001857 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001858
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001859 public void noteStartGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001860 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001861 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001862 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
1863 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001864 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001865 }
1866 mGpsNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001867 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001868 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001869
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001870 public void noteStopGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001871 mGpsNesting--;
1872 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001873 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001874 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
1875 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001876 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001877 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001878 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001879 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 public void noteScreenOnLocked() {
1882 if (!mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001883 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001884 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
1885 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001886 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 mScreenOn = true;
1888 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001889 if (mScreenBrightnessBin >= 0) {
1890 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1891 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001892
1893 // Fake a wake lock, so we consider the device waked as long
1894 // as the screen is on.
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001895 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001896
1897 // Update discharge amounts.
1898 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001899 updateDischargeScreenLevelsLocked(false, true);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001901 }
1902 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001904 public void noteScreenOffLocked() {
1905 if (mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001906 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001907 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
1908 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001909 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001910 mScreenOn = false;
1911 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001912 if (mScreenBrightnessBin >= 0) {
1913 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1914 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001915
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001916 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001917
1918 // Update discharge amounts.
1919 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001920 updateDischargeScreenLevelsLocked(true, false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001921 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001922 }
1923 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001924
Dianne Hackborn617f8772009-03-31 15:04:46 -07001925 public void noteScreenBrightnessLocked(int brightness) {
1926 // Bin the brightness.
1927 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1928 if (bin < 0) bin = 0;
1929 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1930 if (mScreenBrightnessBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001931 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
1932 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001933 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
1934 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001935 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001936 if (mScreenOn) {
1937 if (mScreenBrightnessBin >= 0) {
1938 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1939 }
1940 mScreenBrightnessTimer[bin].startRunningLocked(this);
1941 }
1942 mScreenBrightnessBin = bin;
1943 }
1944 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001945
Christopher Tate4cee7252010-03-19 14:50:40 -07001946 public void noteInputEventAtomic() {
1947 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001948 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001949
Dianne Hackborn617f8772009-03-31 15:04:46 -07001950 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001951 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001952 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001954 public void notePhoneOnLocked() {
1955 if (!mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001956 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001957 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
1958 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001959 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001960 mPhoneOn = true;
1961 mPhoneOnTimer.startRunningLocked(this);
1962 }
1963 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001965 public void notePhoneOffLocked() {
1966 if (mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001967 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001968 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
1969 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001970 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001971 mPhoneOn = false;
1972 mPhoneOnTimer.stopRunningLocked(this);
1973 }
1974 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001975
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001976 void stopAllSignalStrengthTimersLocked(int except) {
Wink Saville52840902011-02-18 12:40:47 -08001977 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001978 if (i == except) {
1979 continue;
1980 }
1981 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1982 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
1983 }
1984 }
1985 }
1986
Dianne Hackborne4a59512010-12-07 11:08:07 -08001987 private int fixPhoneServiceState(int state, int signalBin) {
1988 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
1989 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1990 // to infer that we are scanning from other data.
1991 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08001992 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001993 state = ServiceState.STATE_IN_SERVICE;
1994 }
1995 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001996
Dianne Hackborne4a59512010-12-07 11:08:07 -08001997 return state;
1998 }
1999
2000 private void updateAllPhoneStateLocked(int state, int simState, int bin) {
2001 boolean scanning = false;
2002 boolean newHistory = false;
2003
2004 mPhoneServiceStateRaw = state;
2005 mPhoneSimStateRaw = simState;
2006 mPhoneSignalStrengthBinRaw = bin;
2007
2008 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
2009 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2010 // to infer that we are scanning from other data.
2011 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08002012 && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002013 state = ServiceState.STATE_IN_SERVICE;
2014 }
2015 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002016
2017 // If the phone is powered off, stop all timers.
2018 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002019 bin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002020
Dianne Hackborne4a59512010-12-07 11:08:07 -08002021 // If we are in service, make sure the correct signal string timer is running.
2022 } else if (state == ServiceState.STATE_IN_SERVICE) {
2023 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002024
2025 // If we're out of service, we are in the lowest signal strength
2026 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07002027 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002028 scanning = true;
Wink Saville52840902011-02-18 12:40:47 -08002029 bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002030 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002031 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08002032 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002033 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
2034 + Integer.toHexString(mHistoryCur.states));
Amith Yamasanif37447b2009-10-08 18:28:01 -07002035 mPhoneSignalScanningTimer.startRunningLocked(this);
2036 }
2037 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002038
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002039 if (!scanning) {
2040 // If we are no longer scanning, then stop the scanning timer.
2041 if (mPhoneSignalScanningTimer.isRunningLocked()) {
2042 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
2043 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
2044 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002045 newHistory = true;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002046 mPhoneSignalScanningTimer.stopRunningLocked(this);
2047 }
2048 }
2049
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002050 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002051 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
2052 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002053 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002054 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002055 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002056 mPhoneServiceState = state;
2057 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08002058
2059 if (mPhoneSignalStrengthBin != bin) {
2060 if (mPhoneSignalStrengthBin >= 0) {
2061 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
2062 }
2063 if (bin >= 0) {
2064 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
2065 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
2066 }
2067 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
2068 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
2069 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
2070 + Integer.toHexString(mHistoryCur.states));
2071 newHistory = true;
2072 } else {
2073 stopAllSignalStrengthTimersLocked(-1);
2074 }
2075 mPhoneSignalStrengthBin = bin;
2076 }
2077
2078 if (newHistory) {
2079 addHistoryRecordLocked(SystemClock.elapsedRealtime());
2080 }
2081 }
2082
2083 /**
2084 * Telephony stack updates the phone state.
2085 * @param state phone state from ServiceState.getState()
2086 */
2087 public void notePhoneStateLocked(int state, int simState) {
2088 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002089 }
2090
Wink Savillee9b06d72009-05-18 21:47:50 -07002091 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07002092 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08002093 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08002094 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002095 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002096
Dianne Hackborn627bba72009-03-24 22:32:56 -07002097 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
2098 int bin = DATA_CONNECTION_NONE;
2099 if (hasData) {
2100 switch (dataType) {
2101 case TelephonyManager.NETWORK_TYPE_EDGE:
2102 bin = DATA_CONNECTION_EDGE;
2103 break;
2104 case TelephonyManager.NETWORK_TYPE_GPRS:
2105 bin = DATA_CONNECTION_GPRS;
2106 break;
2107 case TelephonyManager.NETWORK_TYPE_UMTS:
2108 bin = DATA_CONNECTION_UMTS;
2109 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002110 case TelephonyManager.NETWORK_TYPE_CDMA:
2111 bin = DATA_CONNECTION_CDMA;
2112 break;
2113 case TelephonyManager.NETWORK_TYPE_EVDO_0:
2114 bin = DATA_CONNECTION_EVDO_0;
2115 break;
2116 case TelephonyManager.NETWORK_TYPE_EVDO_A:
2117 bin = DATA_CONNECTION_EVDO_A;
2118 break;
2119 case TelephonyManager.NETWORK_TYPE_1xRTT:
2120 bin = DATA_CONNECTION_1xRTT;
2121 break;
2122 case TelephonyManager.NETWORK_TYPE_HSDPA:
2123 bin = DATA_CONNECTION_HSDPA;
2124 break;
2125 case TelephonyManager.NETWORK_TYPE_HSUPA:
2126 bin = DATA_CONNECTION_HSUPA;
2127 break;
2128 case TelephonyManager.NETWORK_TYPE_HSPA:
2129 bin = DATA_CONNECTION_HSPA;
2130 break;
2131 case TelephonyManager.NETWORK_TYPE_IDEN:
2132 bin = DATA_CONNECTION_IDEN;
2133 break;
2134 case TelephonyManager.NETWORK_TYPE_EVDO_B:
2135 bin = DATA_CONNECTION_EVDO_B;
2136 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07002137 case TelephonyManager.NETWORK_TYPE_LTE:
2138 bin = DATA_CONNECTION_LTE;
2139 break;
2140 case TelephonyManager.NETWORK_TYPE_EHRPD:
2141 bin = DATA_CONNECTION_EHRPD;
2142 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07002143 default:
2144 bin = DATA_CONNECTION_OTHER;
2145 break;
2146 }
2147 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002148 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002149 if (mPhoneDataConnectionType != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002150 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
2151 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002152 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
2153 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002154 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07002155 if (mPhoneDataConnectionType >= 0) {
2156 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
2157 }
2158 mPhoneDataConnectionType = bin;
2159 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
2160 }
2161 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002162
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002163 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002164 if (!mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002165 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002166 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
2167 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002168 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002169 mWifiOn = true;
2170 mWifiOnTimer.startRunningLocked(this);
2171 }
2172 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002173
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002174 public void noteWifiOffLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002175 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002176 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002177 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
2178 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002179 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002180 mWifiOn = false;
2181 mWifiOnTimer.stopRunningLocked(this);
2182 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002183 if (mWifiOnUid >= 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002184 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002185 mWifiOnUid = -1;
2186 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002187 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002188
2189 public void noteAudioOnLocked(int uid) {
2190 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002191 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002192 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
2193 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002194 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002195 mAudioOn = true;
2196 mAudioOnTimer.startRunningLocked(this);
2197 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002198 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002199 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002200
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002201 public void noteAudioOffLocked(int uid) {
2202 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002203 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002204 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
2205 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002206 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002207 mAudioOn = false;
2208 mAudioOnTimer.stopRunningLocked(this);
2209 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002210 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002211 }
2212
2213 public void noteVideoOnLocked(int uid) {
2214 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002215 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002216 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
2217 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002218 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002219 mVideoOn = true;
2220 mVideoOnTimer.startRunningLocked(this);
2221 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002222 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002223 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002224
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002225 public void noteVideoOffLocked(int uid) {
2226 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002227 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002228 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
2229 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002230 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002231 mVideoOn = false;
2232 mVideoOnTimer.stopRunningLocked(this);
2233 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002234 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002235 }
2236
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002237 public void noteVibratorOnLocked(int uid, long durationMillis) {
2238 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
2239 }
2240
2241 public void noteVibratorOffLocked(int uid) {
2242 getUidStatsLocked(uid).noteVibratorOffLocked();
2243 }
2244
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002245 public void noteWifiRunningLocked(WorkSource ws) {
2246 if (!mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002247 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002248 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
2249 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002250 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002251 mGlobalWifiRunning = true;
2252 mGlobalWifiRunningTimer.startRunningLocked(this);
2253 int N = ws.size();
2254 for (int i=0; i<N; i++) {
2255 getUidStatsLocked(ws.get(i)).noteWifiRunningLocked();
2256 }
2257 } else {
2258 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002259 }
2260 }
2261
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002262 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
2263 if (mGlobalWifiRunning) {
2264 int N = oldWs.size();
2265 for (int i=0; i<N; i++) {
2266 getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked();
2267 }
2268 N = newWs.size();
2269 for (int i=0; i<N; i++) {
2270 getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked();
2271 }
2272 } else {
2273 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
2274 }
2275 }
2276
2277 public void noteWifiStoppedLocked(WorkSource ws) {
2278 if (mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002279 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002280 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
2281 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002282 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002283 mGlobalWifiRunning = false;
2284 mGlobalWifiRunningTimer.stopRunningLocked(this);
2285 int N = ws.size();
2286 for (int i=0; i<N; i++) {
2287 getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked();
2288 }
2289 } else {
2290 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002291 }
2292 }
2293
The Android Open Source Project10592532009-03-18 17:39:46 -07002294 public void noteBluetoothOnLocked() {
2295 if (!mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002296 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002297 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
2298 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002299 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002300 mBluetoothOn = true;
2301 mBluetoothOnTimer.startRunningLocked(this);
2302 }
2303 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002304
The Android Open Source Project10592532009-03-18 17:39:46 -07002305 public void noteBluetoothOffLocked() {
2306 if (mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002307 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002308 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
2309 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002310 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002311 mBluetoothOn = false;
2312 mBluetoothOnTimer.stopRunningLocked(this);
2313 }
2314 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002315
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002316 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002317
The Android Open Source Project10592532009-03-18 17:39:46 -07002318 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002319 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002320 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002321 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
2322 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002323 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002324 }
2325 mWifiFullLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002326 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002327 }
2328
2329 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002330 mWifiFullLockNesting--;
2331 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002332 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002333 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
2334 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002335 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002336 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002337 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002338 }
2339
Nick Pelly6ccaa542012-06-15 15:22:47 -07002340 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002341
Nick Pelly6ccaa542012-06-15 15:22:47 -07002342 public void noteWifiScanStartedLocked(int uid) {
2343 if (mWifiScanNesting == 0) {
2344 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
2345 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002346 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002347 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002348 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002349 mWifiScanNesting++;
2350 getUidStatsLocked(uid).noteWifiScanStartedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002351 }
2352
Nick Pelly6ccaa542012-06-15 15:22:47 -07002353 public void noteWifiScanStoppedLocked(int uid) {
2354 mWifiScanNesting--;
2355 if (mWifiScanNesting == 0) {
2356 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
2357 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002358 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002359 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002360 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002361 getUidStatsLocked(uid).noteWifiScanStoppedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002362 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002363
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002364 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002365
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002366 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002367 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002368 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002369 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
2370 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002371 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002372 }
2373 mWifiMulticastNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002374 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002375 }
2376
2377 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002378 mWifiMulticastNesting--;
2379 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002380 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002381 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
2382 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002383 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002384 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002385 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002386 }
2387
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002388 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2389 int N = ws.size();
2390 for (int i=0; i<N; i++) {
2391 noteFullWifiLockAcquiredLocked(ws.get(i));
2392 }
2393 }
2394
2395 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
2396 int N = ws.size();
2397 for (int i=0; i<N; i++) {
2398 noteFullWifiLockReleasedLocked(ws.get(i));
2399 }
2400 }
2401
Nick Pelly6ccaa542012-06-15 15:22:47 -07002402 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002403 int N = ws.size();
2404 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07002405 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002406 }
2407 }
2408
Nick Pelly6ccaa542012-06-15 15:22:47 -07002409 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002410 int N = ws.size();
2411 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07002412 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002413 }
2414 }
2415
2416 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
2417 int N = ws.size();
2418 for (int i=0; i<N; i++) {
2419 noteWifiMulticastEnabledLocked(ws.get(i));
2420 }
2421 }
2422
2423 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
2424 int N = ws.size();
2425 for (int i=0; i<N; i++) {
2426 noteWifiMulticastDisabledLocked(ws.get(i));
2427 }
2428 }
2429
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002430 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
2431 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
2432 mMobileIfaces.add(iface);
2433 } else {
2434 mMobileIfaces.remove(iface);
2435 }
2436 }
2437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002439 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002441
Dianne Hackborn617f8772009-03-31 15:04:46 -07002442 @Override public long getScreenBrightnessTime(int brightnessBin,
2443 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002444 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07002445 batteryRealtime, which);
2446 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002447
Dianne Hackborn617f8772009-03-31 15:04:46 -07002448 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002449 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002450 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002453 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002454 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002455
Dianne Hackborn627bba72009-03-24 22:32:56 -07002456 @Override public long getPhoneSignalStrengthTime(int strengthBin,
2457 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002458 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002459 batteryRealtime, which);
2460 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002461
2462 @Override public long getPhoneSignalScanningTime(
2463 long batteryRealtime, int which) {
2464 return mPhoneSignalScanningTimer.getTotalTimeLocked(
2465 batteryRealtime, which);
2466 }
2467
Catherine Liufb900812012-07-17 14:12:56 -05002468 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
2469 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002470 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002471
Dianne Hackborn627bba72009-03-24 22:32:56 -07002472 @Override public long getPhoneDataConnectionTime(int dataType,
2473 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002474 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002475 batteryRealtime, which);
2476 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002477
Dianne Hackborn617f8772009-03-31 15:04:46 -07002478 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002479 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002480 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002481
The Android Open Source Project10592532009-03-18 17:39:46 -07002482 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002483 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002484 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002485
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002486 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) {
2487 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002488 }
2489
The Android Open Source Project10592532009-03-18 17:39:46 -07002490 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002491 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002492 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 @Override public boolean getIsOnBattery() {
2495 return mOnBattery;
2496 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
2499 return mUidStats;
2500 }
2501
2502 /**
2503 * The statistics associated with a particular uid.
2504 */
2505 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507 final int mUid;
2508 long mLoadedTcpBytesReceived;
2509 long mLoadedTcpBytesSent;
2510 long mCurrentTcpBytesReceived;
2511 long mCurrentTcpBytesSent;
2512 long mTcpBytesReceivedAtLastUnplug;
2513 long mTcpBytesSentAtLastUnplug;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002515 // These are not saved/restored when parcelling, since we want
2516 // to return from the parcel with a snapshot of the state.
2517 long mStartedTcpBytesReceived = -1;
2518 long mStartedTcpBytesSent = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002519
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002520 boolean mWifiRunning;
2521 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002522
The Android Open Source Project10592532009-03-18 17:39:46 -07002523 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002524 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002525
Nick Pelly6ccaa542012-06-15 15:22:47 -07002526 boolean mWifiScanStarted;
2527 StopwatchTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002528
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002529 boolean mWifiMulticastEnabled;
2530 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002531
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002532 boolean mAudioTurnedOn;
2533 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002534
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002535 boolean mVideoTurnedOn;
2536 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002537
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002538 BatchTimer mVibratorOnTimer;
2539
Dianne Hackborn617f8772009-03-31 15:04:46 -07002540 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 /**
2543 * The statistics we have collected for this uid's wake locks.
2544 */
2545 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
2546
2547 /**
2548 * The statistics we have collected for this uid's sensor activations.
2549 */
2550 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
2551
2552 /**
2553 * The statistics we have collected for this uid's processes.
2554 */
2555 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
2556
2557 /**
2558 * The statistics we have collected for this uid's processes.
2559 */
2560 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002561
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002562 /**
2563 * The transient wake stats we have collected for this uid's pids.
2564 */
2565 final SparseArray<Pid> mPids = new SparseArray<Pid>();
2566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 public Uid(int uid) {
2568 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002569 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2570 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002571 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002572 mFullWifiLockTimers, mUnpluggables);
Nick Pelly6ccaa542012-06-15 15:22:47 -07002573 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
2574 mWifiScanTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002575 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002576 mWifiMulticastTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002577 }
2578
2579 @Override
2580 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
2581 return mWakelockStats;
2582 }
2583
2584 @Override
2585 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
2586 return mSensorStats;
2587 }
2588
2589 @Override
2590 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
2591 return mProcessStats;
2592 }
2593
2594 @Override
2595 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
2596 return mPackageStats;
2597 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002598
2599 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002600 public int getUid() {
2601 return mUid;
2602 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002603
2604 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 public long getTcpBytesReceived(int which) {
2606 if (which == STATS_LAST) {
2607 return mLoadedTcpBytesReceived;
2608 } else {
2609 long current = computeCurrentTcpBytesReceived();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002610 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002611 current -= mTcpBytesReceivedAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002612 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 current += mLoadedTcpBytesReceived;
2614 }
2615 return current;
2616 }
2617 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002619 public long computeCurrentTcpBytesReceived() {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002620 final long uidRxBytes = getNetworkStatsDetailGroupedByUid().getTotal(
2621 null, mUid).rxBytes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002623 ? (uidRxBytes - mStartedTcpBytesReceived) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002624 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002625
2626 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 public long getTcpBytesSent(int which) {
2628 if (which == STATS_LAST) {
2629 return mLoadedTcpBytesSent;
2630 } else {
2631 long current = computeCurrentTcpBytesSent();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002632 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 current -= mTcpBytesSentAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002634 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002635 current += mLoadedTcpBytesSent;
2636 }
2637 return current;
2638 }
2639 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002640
The Android Open Source Project10592532009-03-18 17:39:46 -07002641 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002642 public void noteWifiRunningLocked() {
2643 if (!mWifiRunning) {
2644 mWifiRunning = true;
2645 if (mWifiRunningTimer == null) {
2646 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2647 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002648 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002649 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002650 }
2651 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002652
Dianne Hackborn617f8772009-03-31 15:04:46 -07002653 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002654 public void noteWifiStoppedLocked() {
2655 if (mWifiRunning) {
2656 mWifiRunning = false;
2657 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002658 }
2659 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002660
Dianne Hackborn617f8772009-03-31 15:04:46 -07002661 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002662 public void noteFullWifiLockAcquiredLocked() {
2663 if (!mFullWifiLockOut) {
2664 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002665 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002666 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002667 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002668 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002669 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2670 }
2671 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002672
The Android Open Source Project10592532009-03-18 17:39:46 -07002673 @Override
2674 public void noteFullWifiLockReleasedLocked() {
2675 if (mFullWifiLockOut) {
2676 mFullWifiLockOut = false;
2677 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2678 }
2679 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002680
The Android Open Source Project10592532009-03-18 17:39:46 -07002681 @Override
Nick Pelly6ccaa542012-06-15 15:22:47 -07002682 public void noteWifiScanStartedLocked() {
2683 if (!mWifiScanStarted) {
2684 mWifiScanStarted = true;
2685 if (mWifiScanTimer == null) {
2686 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
2687 mWifiScanTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002688 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002689 mWifiScanTimer.startRunningLocked(BatteryStatsImpl.this);
The Android Open Source Project10592532009-03-18 17:39:46 -07002690 }
2691 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002692
The Android Open Source Project10592532009-03-18 17:39:46 -07002693 @Override
Nick Pelly6ccaa542012-06-15 15:22:47 -07002694 public void noteWifiScanStoppedLocked() {
2695 if (mWifiScanStarted) {
2696 mWifiScanStarted = false;
2697 mWifiScanTimer.stopRunningLocked(BatteryStatsImpl.this);
The Android Open Source Project10592532009-03-18 17:39:46 -07002698 }
2699 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002700
2701 @Override
2702 public void noteWifiMulticastEnabledLocked() {
2703 if (!mWifiMulticastEnabled) {
2704 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002705 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002706 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002707 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002708 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002709 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
2710 }
2711 }
2712
2713 @Override
2714 public void noteWifiMulticastDisabledLocked() {
2715 if (mWifiMulticastEnabled) {
2716 mWifiMulticastEnabled = false;
2717 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
2718 }
2719 }
2720
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002721 public StopwatchTimer createAudioTurnedOnTimerLocked() {
2722 if (mAudioTurnedOnTimer == null) {
2723 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
2724 null, mUnpluggables);
2725 }
2726 return mAudioTurnedOnTimer;
2727 }
2728
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002729 @Override
2730 public void noteAudioTurnedOnLocked() {
2731 if (!mAudioTurnedOn) {
2732 mAudioTurnedOn = true;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002733 createAudioTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002734 }
2735 }
2736
2737 @Override
2738 public void noteAudioTurnedOffLocked() {
2739 if (mAudioTurnedOn) {
2740 mAudioTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002741 if (mAudioTurnedOnTimer != null) {
2742 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2743 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002744 }
2745 }
2746
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002747 public StopwatchTimer createVideoTurnedOnTimerLocked() {
2748 if (mVideoTurnedOnTimer == null) {
2749 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
2750 null, mUnpluggables);
2751 }
2752 return mVideoTurnedOnTimer;
2753 }
2754
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002755 @Override
2756 public void noteVideoTurnedOnLocked() {
2757 if (!mVideoTurnedOn) {
2758 mVideoTurnedOn = true;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002759 createVideoTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002760 }
2761 }
2762
2763 @Override
2764 public void noteVideoTurnedOffLocked() {
2765 if (mVideoTurnedOn) {
2766 mVideoTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002767 if (mVideoTurnedOnTimer != null) {
2768 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2769 }
2770 }
2771 }
2772
2773 public BatchTimer createVibratorOnTimerLocked() {
2774 if (mVibratorOnTimer == null) {
2775 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
2776 mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal);
2777 }
2778 return mVibratorOnTimer;
2779 }
2780
2781 public void noteVibratorOnLocked(long durationMillis) {
2782 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
2783 }
2784
2785 public void noteVibratorOffLocked() {
2786 if (mVibratorOnTimer != null) {
2787 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002788 }
2789 }
2790
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002791 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002792 public long getWifiRunningTime(long batteryRealtime, int which) {
2793 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002794 return 0;
2795 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002796 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002797 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002798
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002799 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002800 public long getFullWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002801 if (mFullWifiLockTimer == null) {
2802 return 0;
2803 }
Evan Millarc64edde2009-04-18 12:26:32 -07002804 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002805 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002806
2807 @Override
Nick Pelly6ccaa542012-06-15 15:22:47 -07002808 public long getWifiScanTime(long batteryRealtime, int which) {
2809 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002810 return 0;
2811 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002812 return mWifiScanTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002813 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002814
2815 @Override
2816 public long getWifiMulticastTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002817 if (mWifiMulticastTimer == null) {
2818 return 0;
2819 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002820 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
2821 which);
2822 }
2823
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002824 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002825 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
2826 if (mAudioTurnedOnTimer == null) {
2827 return 0;
2828 }
2829 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2830 }
2831
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002832 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002833 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
2834 if (mVideoTurnedOnTimer == null) {
2835 return 0;
2836 }
2837 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2838 }
2839
Dianne Hackborn617f8772009-03-31 15:04:46 -07002840 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002841 public Timer getVibratorOnTimer() {
2842 return mVibratorOnTimer;
2843 }
2844
2845 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07002846 public void noteUserActivityLocked(int type) {
2847 if (mUserActivityCounters == null) {
2848 initUserActivityLocked();
2849 }
Jeff Browndf693de2012-07-27 12:03:38 -07002850 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
2851 mUserActivityCounters[type].stepAtomic();
2852 } else {
2853 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
2854 new Throwable());
2855 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002856 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002857
Dianne Hackborn617f8772009-03-31 15:04:46 -07002858 @Override
2859 public boolean hasUserActivity() {
2860 return mUserActivityCounters != null;
2861 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002862
Dianne Hackborn617f8772009-03-31 15:04:46 -07002863 @Override
2864 public int getUserActivityCount(int type, int which) {
2865 if (mUserActivityCounters == null) {
2866 return 0;
2867 }
Evan Millarc64edde2009-04-18 12:26:32 -07002868 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002869 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002870
Dianne Hackborn617f8772009-03-31 15:04:46 -07002871 void initUserActivityLocked() {
2872 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2873 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2874 mUserActivityCounters[i] = new Counter(mUnpluggables);
2875 }
2876 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002878 public long computeCurrentTcpBytesSent() {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002879 final long uidTxBytes = getNetworkStatsDetailGroupedByUid().getTotal(
2880 null, mUid).txBytes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002881 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002882 ? (uidTxBytes - mStartedTcpBytesSent) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002883 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002884
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002885 /**
2886 * Clear all stats for this uid. Returns true if the uid is completely
2887 * inactive so can be dropped.
2888 */
2889 boolean reset() {
2890 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002891
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002892 if (mWifiRunningTimer != null) {
2893 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false);
2894 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002895 }
2896 if (mFullWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002897 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002898 active |= mFullWifiLockOut;
2899 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002900 if (mWifiScanTimer != null) {
2901 active |= !mWifiScanTimer.reset(BatteryStatsImpl.this, false);
2902 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002903 }
2904 if (mWifiMulticastTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002905 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002906 active |= mWifiMulticastEnabled;
2907 }
2908 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002909 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002910 active |= mAudioTurnedOn;
2911 }
2912 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002913 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002914 active |= mVideoTurnedOn;
2915 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002916 if (mVibratorOnTimer != null) {
2917 if (mVibratorOnTimer.reset(BatteryStatsImpl.this, false)) {
2918 mVibratorOnTimer.detach();
2919 mVibratorOnTimer = null;
2920 } else {
2921 active = true;
2922 }
2923 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002924
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002925 mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0;
2926 mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002927
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002928 if (mUserActivityCounters != null) {
2929 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2930 mUserActivityCounters[i].reset(false);
2931 }
2932 }
2933
2934 if (mWakelockStats.size() > 0) {
2935 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
2936 while (it.hasNext()) {
2937 Map.Entry<String, Wakelock> wakelockEntry = it.next();
2938 Wakelock wl = wakelockEntry.getValue();
2939 if (wl.reset()) {
2940 it.remove();
2941 } else {
2942 active = true;
2943 }
2944 }
2945 }
2946 if (mSensorStats.size() > 0) {
2947 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
2948 while (it.hasNext()) {
2949 Map.Entry<Integer, Sensor> sensorEntry = it.next();
2950 Sensor s = sensorEntry.getValue();
2951 if (s.reset()) {
2952 it.remove();
2953 } else {
2954 active = true;
2955 }
2956 }
2957 }
2958 if (mProcessStats.size() > 0) {
2959 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
2960 while (it.hasNext()) {
2961 Map.Entry<String, Proc> procEntry = it.next();
2962 procEntry.getValue().detach();
2963 }
2964 mProcessStats.clear();
2965 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002966 if (mPids.size() > 0) {
2967 for (int i=0; !active && i<mPids.size(); i++) {
2968 Pid pid = mPids.valueAt(i);
2969 if (pid.mWakeStart != 0) {
2970 active = true;
2971 }
2972 }
2973 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002974 if (mPackageStats.size() > 0) {
2975 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
2976 while (it.hasNext()) {
2977 Map.Entry<String, Pkg> pkgEntry = it.next();
2978 Pkg p = pkgEntry.getValue();
2979 p.detach();
2980 if (p.mServiceStats.size() > 0) {
2981 Iterator<Map.Entry<String, Pkg.Serv>> it2
2982 = p.mServiceStats.entrySet().iterator();
2983 while (it2.hasNext()) {
2984 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
2985 servEntry.getValue().detach();
2986 }
2987 }
2988 }
2989 mPackageStats.clear();
2990 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002991
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002992 mPids.clear();
2993
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002994 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002995 if (mWifiRunningTimer != null) {
2996 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002997 }
2998 if (mFullWifiLockTimer != null) {
2999 mFullWifiLockTimer.detach();
3000 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003001 if (mWifiScanTimer != null) {
3002 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003003 }
3004 if (mWifiMulticastTimer != null) {
3005 mWifiMulticastTimer.detach();
3006 }
3007 if (mAudioTurnedOnTimer != null) {
3008 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003009 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003010 }
3011 if (mVideoTurnedOnTimer != null) {
3012 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003013 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003014 }
3015 if (mUserActivityCounters != null) {
3016 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3017 mUserActivityCounters[i].detach();
3018 }
3019 }
3020 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003021
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003022 return !active;
3023 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3026 out.writeInt(mWakelockStats.size());
3027 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
3028 out.writeString(wakelockEntry.getKey());
3029 Uid.Wakelock wakelock = wakelockEntry.getValue();
3030 wakelock.writeToParcelLocked(out, batteryRealtime);
3031 }
3032
3033 out.writeInt(mSensorStats.size());
3034 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
3035 out.writeInt(sensorEntry.getKey());
3036 Uid.Sensor sensor = sensorEntry.getValue();
3037 sensor.writeToParcelLocked(out, batteryRealtime);
3038 }
3039
3040 out.writeInt(mProcessStats.size());
3041 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
3042 out.writeString(procEntry.getKey());
3043 Uid.Proc proc = procEntry.getValue();
3044 proc.writeToParcelLocked(out);
3045 }
3046
3047 out.writeInt(mPackageStats.size());
3048 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
3049 out.writeString(pkgEntry.getKey());
3050 Uid.Pkg pkg = pkgEntry.getValue();
3051 pkg.writeToParcelLocked(out);
3052 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 out.writeLong(mLoadedTcpBytesReceived);
3055 out.writeLong(mLoadedTcpBytesSent);
3056 out.writeLong(computeCurrentTcpBytesReceived());
3057 out.writeLong(computeCurrentTcpBytesSent());
3058 out.writeLong(mTcpBytesReceivedAtLastUnplug);
3059 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003060 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003061 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003062 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003063 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003064 out.writeInt(0);
3065 }
3066 if (mFullWifiLockTimer != null) {
3067 out.writeInt(1);
3068 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
3069 } else {
3070 out.writeInt(0);
3071 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003072 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003073 out.writeInt(1);
Nick Pelly6ccaa542012-06-15 15:22:47 -07003074 mWifiScanTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003075 } else {
3076 out.writeInt(0);
3077 }
3078 if (mWifiMulticastTimer != null) {
3079 out.writeInt(1);
3080 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
3081 } else {
3082 out.writeInt(0);
3083 }
3084 if (mAudioTurnedOnTimer != null) {
3085 out.writeInt(1);
3086 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
3087 } else {
3088 out.writeInt(0);
3089 }
3090 if (mVideoTurnedOnTimer != null) {
3091 out.writeInt(1);
3092 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
3093 } else {
3094 out.writeInt(0);
3095 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003096 if (mVibratorOnTimer != null) {
3097 out.writeInt(1);
3098 mVibratorOnTimer.writeToParcel(out, batteryRealtime);
3099 } else {
3100 out.writeInt(0);
3101 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003102 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003103 out.writeInt(1);
3104 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3105 mUserActivityCounters[i].writeToParcel(out);
3106 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003107 } else {
3108 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003110 }
3111
3112 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3113 int numWakelocks = in.readInt();
3114 mWakelockStats.clear();
3115 for (int j = 0; j < numWakelocks; j++) {
3116 String wakelockName = in.readString();
3117 Uid.Wakelock wakelock = new Wakelock();
3118 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackbornc24ab862011-10-18 15:55:03 -07003119 // We will just drop some random set of wakelocks if
3120 // the previous run of the system was an older version
3121 // that didn't impose a limit.
3122 mWakelockStats.put(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003123 }
3124
3125 int numSensors = in.readInt();
3126 mSensorStats.clear();
3127 for (int k = 0; k < numSensors; k++) {
3128 int sensorNumber = in.readInt();
3129 Uid.Sensor sensor = new Sensor(sensorNumber);
3130 sensor.readFromParcelLocked(mUnpluggables, in);
3131 mSensorStats.put(sensorNumber, sensor);
3132 }
3133
3134 int numProcs = in.readInt();
3135 mProcessStats.clear();
3136 for (int k = 0; k < numProcs; k++) {
3137 String processName = in.readString();
3138 Uid.Proc proc = new Proc();
3139 proc.readFromParcelLocked(in);
3140 mProcessStats.put(processName, proc);
3141 }
3142
3143 int numPkgs = in.readInt();
3144 mPackageStats.clear();
3145 for (int l = 0; l < numPkgs; l++) {
3146 String packageName = in.readString();
3147 Uid.Pkg pkg = new Pkg();
3148 pkg.readFromParcelLocked(in);
3149 mPackageStats.put(packageName, pkg);
3150 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003152 mLoadedTcpBytesReceived = in.readLong();
3153 mLoadedTcpBytesSent = in.readLong();
3154 mCurrentTcpBytesReceived = in.readLong();
3155 mCurrentTcpBytesSent = in.readLong();
3156 mTcpBytesReceivedAtLastUnplug = in.readLong();
3157 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003158 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003159 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003160 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
3161 mWifiRunningTimers, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003162 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003163 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003164 }
3165 mFullWifiLockOut = false;
3166 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003167 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003168 mFullWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003169 } else {
3170 mFullWifiLockTimer = null;
3171 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003172 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003173 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003174 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
3175 mWifiScanTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003176 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003177 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003178 }
3179 mWifiMulticastEnabled = false;
3180 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003181 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003182 mWifiMulticastTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003183 } else {
3184 mWifiMulticastTimer = null;
3185 }
3186 mAudioTurnedOn = false;
3187 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003188 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003189 null, mUnpluggables, in);
3190 } else {
3191 mAudioTurnedOnTimer = null;
3192 }
3193 mVideoTurnedOn = false;
3194 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003195 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003196 null, mUnpluggables, in);
3197 } else {
3198 mVideoTurnedOnTimer = null;
3199 }
3200 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003201 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
3202 mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal, in);
3203 } else {
3204 mVibratorOnTimer = null;
3205 }
3206 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003207 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
3208 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3209 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
3210 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003211 } else {
3212 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07003213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003214 }
3215
3216 /**
3217 * The statistics associated with a particular wake lock.
3218 */
3219 public final class Wakelock extends BatteryStats.Uid.Wakelock {
3220 /**
3221 * How long (in ms) this uid has been keeping the device partially awake.
3222 */
Evan Millarc64edde2009-04-18 12:26:32 -07003223 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224
3225 /**
3226 * How long (in ms) this uid has been keeping the device fully awake.
3227 */
Evan Millarc64edde2009-04-18 12:26:32 -07003228 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003229
3230 /**
3231 * How long (in ms) this uid has had a window keeping the device awake.
3232 */
Evan Millarc64edde2009-04-18 12:26:32 -07003233 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003234
3235 /**
3236 * Reads a possibly null Timer from a Parcel. The timer is associated with the
3237 * proper timer pool from the given BatteryStatsImpl object.
3238 *
3239 * @param in the Parcel to be read from.
3240 * return a new Timer, or null.
3241 */
Evan Millarc64edde2009-04-18 12:26:32 -07003242 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003243 ArrayList<Unpluggable> unpluggables, Parcel in) {
3244 if (in.readInt() == 0) {
3245 return null;
3246 }
3247
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003248 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003249 }
3250
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003251 boolean reset() {
3252 boolean wlactive = false;
3253 if (mTimerFull != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003254 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003255 }
3256 if (mTimerPartial != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003257 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003258 }
3259 if (mTimerWindow != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003260 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003261 }
3262 if (!wlactive) {
3263 if (mTimerFull != null) {
3264 mTimerFull.detach();
3265 mTimerFull = null;
3266 }
3267 if (mTimerPartial != null) {
3268 mTimerPartial.detach();
3269 mTimerPartial = null;
3270 }
3271 if (mTimerWindow != null) {
3272 mTimerWindow.detach();
3273 mTimerWindow = null;
3274 }
3275 }
3276 return !wlactive;
3277 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003279 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3280 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
3281 mPartialTimers, unpluggables, in);
3282 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
3283 mFullTimers, unpluggables, in);
3284 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
3285 mWindowTimers, unpluggables, in);
3286 }
3287
3288 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3289 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
3290 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
3291 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
3292 }
3293
3294 @Override
3295 public Timer getWakeTime(int type) {
3296 switch (type) {
3297 case WAKE_TYPE_FULL: return mTimerFull;
3298 case WAKE_TYPE_PARTIAL: return mTimerPartial;
3299 case WAKE_TYPE_WINDOW: return mTimerWindow;
3300 default: throw new IllegalArgumentException("type = " + type);
3301 }
3302 }
3303 }
3304
3305 public final class Sensor extends BatteryStats.Uid.Sensor {
3306 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07003307 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 public Sensor(int handle) {
3310 mHandle = handle;
3311 }
3312
Evan Millarc64edde2009-04-18 12:26:32 -07003313 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003314 Parcel in) {
3315 if (in.readInt() == 0) {
3316 return null;
3317 }
3318
Evan Millarc64edde2009-04-18 12:26:32 -07003319 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003321 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003322 mSensorTimers.put(mHandle, pool);
3323 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003324 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325 }
3326
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003327 boolean reset() {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003328 if (mTimer.reset(BatteryStatsImpl.this, true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003329 mTimer = null;
3330 return true;
3331 }
3332 return false;
3333 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3336 mTimer = readTimerFromParcel(unpluggables, in);
3337 }
3338
3339 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3340 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
3341 }
3342
3343 @Override
3344 public Timer getSensorTime() {
3345 return mTimer;
3346 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003347
3348 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 public int getHandle() {
3350 return mHandle;
3351 }
3352 }
3353
3354 /**
3355 * The statistics associated with a particular process.
3356 */
3357 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
3358 /**
3359 * Total time (in 1/100 sec) spent executing in user code.
3360 */
3361 long mUserTime;
3362
3363 /**
3364 * Total time (in 1/100 sec) spent executing in kernel code.
3365 */
3366 long mSystemTime;
3367
3368 /**
3369 * Number of times the process has been started.
3370 */
3371 int mStarts;
3372
3373 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003374 * Amount of time the process was running in the foreground.
3375 */
3376 long mForegroundTime;
3377
3378 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003379 * The amount of user time loaded from a previous save.
3380 */
3381 long mLoadedUserTime;
3382
3383 /**
3384 * The amount of system time loaded from a previous save.
3385 */
3386 long mLoadedSystemTime;
3387
3388 /**
3389 * The number of times the process has started from a previous save.
3390 */
3391 int mLoadedStarts;
3392
3393 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003394 * The amount of foreground time loaded from a previous save.
3395 */
3396 long mLoadedForegroundTime;
3397
3398 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003399 * The amount of user time loaded from the previous run.
3400 */
3401 long mLastUserTime;
3402
3403 /**
3404 * The amount of system time loaded from the previous run.
3405 */
3406 long mLastSystemTime;
3407
3408 /**
3409 * The number of times the process has started from the previous run.
3410 */
3411 int mLastStarts;
3412
3413 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003414 * The amount of foreground time loaded from the previous run
3415 */
3416 long mLastForegroundTime;
3417
3418 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003419 * The amount of user time when last unplugged.
3420 */
3421 long mUnpluggedUserTime;
3422
3423 /**
3424 * The amount of system time when last unplugged.
3425 */
3426 long mUnpluggedSystemTime;
3427
3428 /**
3429 * The number of times the process has started before unplugged.
3430 */
3431 int mUnpluggedStarts;
3432
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003433 /**
3434 * The amount of foreground time since unplugged.
3435 */
3436 long mUnpluggedForegroundTime;
3437
Amith Yamasanie43530a2009-08-21 13:11:37 -07003438 SamplingCounter[] mSpeedBins;
3439
Dianne Hackborn287952c2010-09-22 22:34:31 -07003440 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003442 Proc() {
3443 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003444 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003445 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003446
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003447 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003448 mUnpluggedUserTime = mUserTime;
3449 mUnpluggedSystemTime = mSystemTime;
3450 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003451 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 }
3453
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003454 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003455 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003456
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003457 void detach() {
3458 mUnpluggables.remove(this);
3459 for (int i = 0; i < mSpeedBins.length; i++) {
3460 SamplingCounter c = mSpeedBins[i];
3461 if (c != null) {
3462 mUnpluggables.remove(c);
3463 mSpeedBins[i] = null;
3464 }
3465 }
3466 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003467
Dianne Hackborn287952c2010-09-22 22:34:31 -07003468 public int countExcessivePowers() {
3469 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003470 }
3471
Dianne Hackborn287952c2010-09-22 22:34:31 -07003472 public ExcessivePower getExcessivePower(int i) {
3473 if (mExcessivePower != null) {
3474 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003475 }
3476 return null;
3477 }
3478
3479 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003480 if (mExcessivePower == null) {
3481 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003482 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07003483 ExcessivePower ew = new ExcessivePower();
3484 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003485 ew.overTime = overTime;
3486 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07003487 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003488 }
3489
Dianne Hackborn287952c2010-09-22 22:34:31 -07003490 public void addExcessiveCpu(long overTime, long usedTime) {
3491 if (mExcessivePower == null) {
3492 mExcessivePower = new ArrayList<ExcessivePower>();
3493 }
3494 ExcessivePower ew = new ExcessivePower();
3495 ew.type = ExcessivePower.TYPE_CPU;
3496 ew.overTime = overTime;
3497 ew.usedTime = usedTime;
3498 mExcessivePower.add(ew);
3499 }
3500
3501 void writeExcessivePowerToParcelLocked(Parcel out) {
3502 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003503 out.writeInt(0);
3504 return;
3505 }
3506
Dianne Hackborn287952c2010-09-22 22:34:31 -07003507 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003508 out.writeInt(N);
3509 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003510 ExcessivePower ew = mExcessivePower.get(i);
3511 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003512 out.writeLong(ew.overTime);
3513 out.writeLong(ew.usedTime);
3514 }
3515 }
3516
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003517 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003518 final int N = in.readInt();
3519 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003520 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003521 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003522 }
3523
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003524 if (N > 10000) {
3525 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
3526 return false;
3527 }
3528
Dianne Hackborn287952c2010-09-22 22:34:31 -07003529 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003530 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003531 ExcessivePower ew = new ExcessivePower();
3532 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003533 ew.overTime = in.readLong();
3534 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07003535 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003536 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003537 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003538 }
3539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003540 void writeToParcelLocked(Parcel out) {
3541 out.writeLong(mUserTime);
3542 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003543 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 out.writeInt(mStarts);
3545 out.writeLong(mLoadedUserTime);
3546 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003547 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 out.writeLong(mUnpluggedUserTime);
3550 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003551 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003552 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003553
3554 out.writeInt(mSpeedBins.length);
3555 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003556 SamplingCounter c = mSpeedBins[i];
3557 if (c != null) {
3558 out.writeInt(1);
3559 c.writeToParcel(out);
3560 } else {
3561 out.writeInt(0);
3562 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003563 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003564
Dianne Hackborn287952c2010-09-22 22:34:31 -07003565 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003566 }
3567
3568 void readFromParcelLocked(Parcel in) {
3569 mUserTime = in.readLong();
3570 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003571 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 mStarts = in.readInt();
3573 mLoadedUserTime = in.readLong();
3574 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003575 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003576 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003577 mLastUserTime = 0;
3578 mLastSystemTime = 0;
3579 mLastForegroundTime = 0;
3580 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003581 mUnpluggedUserTime = in.readLong();
3582 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003583 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003584 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07003585
3586 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003587 int steps = getCpuSpeedSteps();
3588 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07003589 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003590 if (in.readInt() != 0) {
3591 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
3592 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003593 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003594
Dianne Hackborn287952c2010-09-22 22:34:31 -07003595 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003596 }
3597
3598 public BatteryStatsImpl getBatteryStats() {
3599 return BatteryStatsImpl.this;
3600 }
3601
3602 public void addCpuTimeLocked(int utime, int stime) {
3603 mUserTime += utime;
3604 mSystemTime += stime;
3605 }
3606
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003607 public void addForegroundTimeLocked(long ttime) {
3608 mForegroundTime += ttime;
3609 }
3610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003611 public void incStartsLocked() {
3612 mStarts++;
3613 }
3614
3615 @Override
3616 public long getUserTime(int which) {
3617 long val;
3618 if (which == STATS_LAST) {
3619 val = mLastUserTime;
3620 } else {
3621 val = mUserTime;
3622 if (which == STATS_CURRENT) {
3623 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003624 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003625 val -= mUnpluggedUserTime;
3626 }
3627 }
3628 return val;
3629 }
3630
3631 @Override
3632 public long getSystemTime(int which) {
3633 long val;
3634 if (which == STATS_LAST) {
3635 val = mLastSystemTime;
3636 } else {
3637 val = mSystemTime;
3638 if (which == STATS_CURRENT) {
3639 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003640 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 val -= mUnpluggedSystemTime;
3642 }
3643 }
3644 return val;
3645 }
3646
3647 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003648 public long getForegroundTime(int which) {
3649 long val;
3650 if (which == STATS_LAST) {
3651 val = mLastForegroundTime;
3652 } else {
3653 val = mForegroundTime;
3654 if (which == STATS_CURRENT) {
3655 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003656 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003657 val -= mUnpluggedForegroundTime;
3658 }
3659 }
3660 return val;
3661 }
3662
3663 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 public int getStarts(int which) {
3665 int val;
3666 if (which == STATS_LAST) {
3667 val = mLastStarts;
3668 } else {
3669 val = mStarts;
3670 if (which == STATS_CURRENT) {
3671 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003672 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003673 val -= mUnpluggedStarts;
3674 }
3675 }
3676 return val;
3677 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003678
3679 /* Called by ActivityManagerService when CPU times are updated. */
3680 public void addSpeedStepTimes(long[] values) {
3681 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003682 long amt = values[i];
3683 if (amt != 0) {
3684 SamplingCounter c = mSpeedBins[i];
3685 if (c == null) {
3686 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
3687 }
3688 c.addCountAtomic(values[i]);
3689 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003690 }
3691 }
3692
3693 @Override
3694 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
3695 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003696 SamplingCounter c = mSpeedBins[speedStep];
3697 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07003698 } else {
3699 return 0;
3700 }
3701 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003702 }
3703
3704 /**
3705 * The statistics associated with a particular package.
3706 */
3707 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
3708 /**
3709 * Number of times this package has done something that could wake up the
3710 * device from sleep.
3711 */
3712 int mWakeups;
3713
3714 /**
3715 * Number of things that could wake up the device loaded from a
3716 * previous save.
3717 */
3718 int mLoadedWakeups;
3719
3720 /**
3721 * Number of things that could wake up the device as of the
3722 * last run.
3723 */
3724 int mLastWakeups;
3725
3726 /**
3727 * Number of things that could wake up the device as of the
3728 * last run.
3729 */
3730 int mUnpluggedWakeups;
3731
3732 /**
3733 * The statics we have collected for this package's services.
3734 */
3735 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
3736
3737 Pkg() {
3738 mUnpluggables.add(this);
3739 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003740
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003741 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003742 mUnpluggedWakeups = mWakeups;
3743 }
3744
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003745 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003747
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003748 void detach() {
3749 mUnpluggables.remove(this);
3750 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003752 void readFromParcelLocked(Parcel in) {
3753 mWakeups = in.readInt();
3754 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003755 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003756 mUnpluggedWakeups = in.readInt();
3757
3758 int numServs = in.readInt();
3759 mServiceStats.clear();
3760 for (int m = 0; m < numServs; m++) {
3761 String serviceName = in.readString();
3762 Uid.Pkg.Serv serv = new Serv();
3763 mServiceStats.put(serviceName, serv);
3764
3765 serv.readFromParcelLocked(in);
3766 }
3767 }
3768
3769 void writeToParcelLocked(Parcel out) {
3770 out.writeInt(mWakeups);
3771 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003772 out.writeInt(mUnpluggedWakeups);
3773
3774 out.writeInt(mServiceStats.size());
3775 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
3776 out.writeString(servEntry.getKey());
3777 Uid.Pkg.Serv serv = servEntry.getValue();
3778
3779 serv.writeToParcelLocked(out);
3780 }
3781 }
3782
3783 @Override
3784 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
3785 return mServiceStats;
3786 }
3787
3788 @Override
3789 public int getWakeups(int which) {
3790 int val;
3791 if (which == STATS_LAST) {
3792 val = mLastWakeups;
3793 } else {
3794 val = mWakeups;
3795 if (which == STATS_CURRENT) {
3796 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003797 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 val -= mUnpluggedWakeups;
3799 }
3800 }
3801
3802 return val;
3803 }
3804
3805 /**
3806 * The statistics associated with a particular service.
3807 */
3808 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
3809 /**
3810 * Total time (ms in battery uptime) the service has been left started.
3811 */
3812 long mStartTime;
3813
3814 /**
3815 * If service has been started and not yet stopped, this is
3816 * when it was started.
3817 */
3818 long mRunningSince;
3819
3820 /**
3821 * True if we are currently running.
3822 */
3823 boolean mRunning;
3824
3825 /**
3826 * Total number of times startService() has been called.
3827 */
3828 int mStarts;
3829
3830 /**
3831 * Total time (ms in battery uptime) the service has been left launched.
3832 */
3833 long mLaunchedTime;
3834
3835 /**
3836 * If service has been launched and not yet exited, this is
3837 * when it was launched (ms in battery uptime).
3838 */
3839 long mLaunchedSince;
3840
3841 /**
3842 * True if we are currently launched.
3843 */
3844 boolean mLaunched;
3845
3846 /**
3847 * Total number times the service has been launched.
3848 */
3849 int mLaunches;
3850
3851 /**
3852 * The amount of time spent started loaded from a previous save
3853 * (ms in battery uptime).
3854 */
3855 long mLoadedStartTime;
3856
3857 /**
3858 * The number of starts loaded from a previous save.
3859 */
3860 int mLoadedStarts;
3861
3862 /**
3863 * The number of launches loaded from a previous save.
3864 */
3865 int mLoadedLaunches;
3866
3867 /**
3868 * The amount of time spent started as of the last run (ms
3869 * in battery uptime).
3870 */
3871 long mLastStartTime;
3872
3873 /**
3874 * The number of starts as of the last run.
3875 */
3876 int mLastStarts;
3877
3878 /**
3879 * The number of launches as of the last run.
3880 */
3881 int mLastLaunches;
3882
3883 /**
3884 * The amount of time spent started when last unplugged (ms
3885 * in battery uptime).
3886 */
3887 long mUnpluggedStartTime;
3888
3889 /**
3890 * The number of starts when last unplugged.
3891 */
3892 int mUnpluggedStarts;
3893
3894 /**
3895 * The number of launches when last unplugged.
3896 */
3897 int mUnpluggedLaunches;
3898
3899 Serv() {
3900 mUnpluggables.add(this);
3901 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003902
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003903 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
3905 mUnpluggedStarts = mStarts;
3906 mUnpluggedLaunches = mLaunches;
3907 }
3908
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003909 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003911
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003912 void detach() {
3913 mUnpluggables.remove(this);
3914 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003916 void readFromParcelLocked(Parcel in) {
3917 mStartTime = in.readLong();
3918 mRunningSince = in.readLong();
3919 mRunning = in.readInt() != 0;
3920 mStarts = in.readInt();
3921 mLaunchedTime = in.readLong();
3922 mLaunchedSince = in.readLong();
3923 mLaunched = in.readInt() != 0;
3924 mLaunches = in.readInt();
3925 mLoadedStartTime = in.readLong();
3926 mLoadedStarts = in.readInt();
3927 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003928 mLastStartTime = 0;
3929 mLastStarts = 0;
3930 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 mUnpluggedStartTime = in.readLong();
3932 mUnpluggedStarts = in.readInt();
3933 mUnpluggedLaunches = in.readInt();
3934 }
3935
3936 void writeToParcelLocked(Parcel out) {
3937 out.writeLong(mStartTime);
3938 out.writeLong(mRunningSince);
3939 out.writeInt(mRunning ? 1 : 0);
3940 out.writeInt(mStarts);
3941 out.writeLong(mLaunchedTime);
3942 out.writeLong(mLaunchedSince);
3943 out.writeInt(mLaunched ? 1 : 0);
3944 out.writeInt(mLaunches);
3945 out.writeLong(mLoadedStartTime);
3946 out.writeInt(mLoadedStarts);
3947 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 out.writeLong(mUnpluggedStartTime);
3949 out.writeInt(mUnpluggedStarts);
3950 out.writeInt(mUnpluggedLaunches);
3951 }
3952
3953 long getLaunchTimeToNowLocked(long batteryUptime) {
3954 if (!mLaunched) return mLaunchedTime;
3955 return mLaunchedTime + batteryUptime - mLaunchedSince;
3956 }
3957
3958 long getStartTimeToNowLocked(long batteryUptime) {
3959 if (!mRunning) return mStartTime;
3960 return mStartTime + batteryUptime - mRunningSince;
3961 }
3962
3963 public void startLaunchedLocked() {
3964 if (!mLaunched) {
3965 mLaunches++;
3966 mLaunchedSince = getBatteryUptimeLocked();
3967 mLaunched = true;
3968 }
3969 }
3970
3971 public void stopLaunchedLocked() {
3972 if (mLaunched) {
3973 long time = getBatteryUptimeLocked() - mLaunchedSince;
3974 if (time > 0) {
3975 mLaunchedTime += time;
3976 } else {
3977 mLaunches--;
3978 }
3979 mLaunched = false;
3980 }
3981 }
3982
3983 public void startRunningLocked() {
3984 if (!mRunning) {
3985 mStarts++;
3986 mRunningSince = getBatteryUptimeLocked();
3987 mRunning = true;
3988 }
3989 }
3990
3991 public void stopRunningLocked() {
3992 if (mRunning) {
3993 long time = getBatteryUptimeLocked() - mRunningSince;
3994 if (time > 0) {
3995 mStartTime += time;
3996 } else {
3997 mStarts--;
3998 }
3999 mRunning = false;
4000 }
4001 }
4002
4003 public BatteryStatsImpl getBatteryStats() {
4004 return BatteryStatsImpl.this;
4005 }
4006
4007 @Override
4008 public int getLaunches(int which) {
4009 int val;
4010
4011 if (which == STATS_LAST) {
4012 val = mLastLaunches;
4013 } else {
4014 val = mLaunches;
4015 if (which == STATS_CURRENT) {
4016 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004017 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004018 val -= mUnpluggedLaunches;
4019 }
4020 }
4021
4022 return val;
4023 }
4024
4025 @Override
4026 public long getStartTime(long now, int which) {
4027 long val;
4028 if (which == STATS_LAST) {
4029 val = mLastStartTime;
4030 } else {
4031 val = getStartTimeToNowLocked(now);
4032 if (which == STATS_CURRENT) {
4033 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004034 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004035 val -= mUnpluggedStartTime;
4036 }
4037 }
4038
4039 return val;
4040 }
4041
4042 @Override
4043 public int getStarts(int which) {
4044 int val;
4045 if (which == STATS_LAST) {
4046 val = mLastStarts;
4047 } else {
4048 val = mStarts;
4049 if (which == STATS_CURRENT) {
4050 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004051 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 val -= mUnpluggedStarts;
4053 }
4054 }
4055
4056 return val;
4057 }
4058 }
4059
4060 public BatteryStatsImpl getBatteryStats() {
4061 return BatteryStatsImpl.this;
4062 }
4063
4064 public void incWakeupsLocked() {
4065 mWakeups++;
4066 }
4067
4068 final Serv newServiceStatsLocked() {
4069 return new Serv();
4070 }
4071 }
4072
4073 /**
4074 * Retrieve the statistics object for a particular process, creating
4075 * if needed.
4076 */
4077 public Proc getProcessStatsLocked(String name) {
4078 Proc ps = mProcessStats.get(name);
4079 if (ps == null) {
4080 ps = new Proc();
4081 mProcessStats.put(name, ps);
4082 }
4083
4084 return ps;
4085 }
4086
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004087 public SparseArray<? extends Pid> getPidStats() {
4088 return mPids;
4089 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004090
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004091 public Pid getPidStatsLocked(int pid) {
4092 Pid p = mPids.get(pid);
4093 if (p == null) {
4094 p = new Pid();
4095 mPids.put(pid, p);
4096 }
4097 return p;
4098 }
4099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004100 /**
4101 * Retrieve the statistics object for a particular service, creating
4102 * if needed.
4103 */
4104 public Pkg getPackageStatsLocked(String name) {
4105 Pkg ps = mPackageStats.get(name);
4106 if (ps == null) {
4107 ps = new Pkg();
4108 mPackageStats.put(name, ps);
4109 }
4110
4111 return ps;
4112 }
4113
4114 /**
4115 * Retrieve the statistics object for a particular service, creating
4116 * if needed.
4117 */
4118 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
4119 Pkg ps = getPackageStatsLocked(pkg);
4120 Pkg.Serv ss = ps.mServiceStats.get(serv);
4121 if (ss == null) {
4122 ss = ps.newServiceStatsLocked();
4123 ps.mServiceStats.put(serv, ss);
4124 }
4125
4126 return ss;
4127 }
4128
Evan Millarc64edde2009-04-18 12:26:32 -07004129 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 Wakelock wl = mWakelockStats.get(name);
4131 if (wl == null) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07004132 final int N = mWakelockStats.size();
Dianne Hackbornaf17baa2013-05-09 15:27:47 -07004133 if (N > MAX_WAKELOCKS_PER_UID) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004134 name = BATCHED_WAKELOCK_NAME;
4135 wl = mWakelockStats.get(name);
4136 }
4137 if (wl == null) {
4138 wl = new Wakelock();
4139 mWakelockStats.put(name, wl);
4140 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 }
Evan Millarc64edde2009-04-18 12:26:32 -07004142 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004143 switch (type) {
4144 case WAKE_TYPE_PARTIAL:
4145 t = wl.mTimerPartial;
4146 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004147 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
4148 mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004149 wl.mTimerPartial = t;
4150 }
4151 return t;
4152 case WAKE_TYPE_FULL:
4153 t = wl.mTimerFull;
4154 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004155 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
4156 mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004157 wl.mTimerFull = t;
4158 }
4159 return t;
4160 case WAKE_TYPE_WINDOW:
4161 t = wl.mTimerWindow;
4162 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004163 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
4164 mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004165 wl.mTimerWindow = t;
4166 }
4167 return t;
4168 default:
4169 throw new IllegalArgumentException("type=" + type);
4170 }
4171 }
4172
Evan Millarc64edde2009-04-18 12:26:32 -07004173 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004174 Sensor se = mSensorStats.get(sensor);
4175 if (se == null) {
4176 if (!create) {
4177 return null;
4178 }
4179 se = new Sensor(sensor);
4180 mSensorStats.put(sensor, se);
4181 }
Evan Millarc64edde2009-04-18 12:26:32 -07004182 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004183 if (t != null) {
4184 return t;
4185 }
Evan Millarc64edde2009-04-18 12:26:32 -07004186 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004187 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07004188 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004189 mSensorTimers.put(sensor, timers);
4190 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004191 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004192 se.mTimer = t;
4193 return t;
4194 }
4195
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004196 public void noteStartWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07004197 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004198 if (t != null) {
4199 t.startRunningLocked(BatteryStatsImpl.this);
4200 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07004201 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004202 Pid p = getPidStatsLocked(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07004203 if (p.mWakeStart == 0) {
4204 p.mWakeStart = SystemClock.elapsedRealtime();
4205 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004206 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 }
4208
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004209 public void noteStopWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07004210 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004211 if (t != null) {
4212 t.stopRunningLocked(BatteryStatsImpl.this);
4213 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07004214 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004215 Pid p = mPids.get(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07004216 if (p != null && p.mWakeStart != 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004217 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
4218 p.mWakeStart = 0;
4219 }
4220 }
4221 }
4222
4223 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
4224 Proc p = getProcessStatsLocked(proc);
4225 if (p != null) {
4226 p.addExcessiveWake(overTime, usedTime);
4227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004229
Dianne Hackborn287952c2010-09-22 22:34:31 -07004230 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
4231 Proc p = getProcessStatsLocked(proc);
4232 if (p != null) {
4233 p.addExcessiveCpu(overTime, usedTime);
4234 }
4235 }
4236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004237 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07004238 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004239 if (t != null) {
4240 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 }
4243
4244 public void noteStopSensor(int sensor) {
4245 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07004246 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004247 if (t != null) {
4248 t.stopRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004252 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004253 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 if (t != null) {
4255 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004256 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004257 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004259 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004260 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004261 if (t != null) {
4262 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004264 }
4265
4266 public BatteryStatsImpl getBatteryStats() {
4267 return BatteryStatsImpl.this;
4268 }
4269 }
4270
4271 public BatteryStatsImpl(String filename) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004272 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004273 mHandler = new MyHandler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004274 mStartCount++;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004275 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004276 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004277 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004278 }
4279 mInputEventCounter = new Counter(mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004280 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
Wink Saville52840902011-02-18 12:40:47 -08004281 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004282 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004283 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004284 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004285 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004286 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004287 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004288 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004289 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004290 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
4291 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
4292 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004294 initTimes();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004295 mTrackBatteryPastUptime = 0;
4296 mTrackBatteryPastRealtime = 0;
4297 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4298 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4299 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4300 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07004301 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004302 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07004303 mDischargeCurrentLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004304 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004305 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 }
4307
4308 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004309 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004310 mHandler = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004311 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 readFromParcel(p);
4313 }
4314
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004315 public void setCallback(BatteryCallback cb) {
4316 mCallback = cb;
4317 }
4318
Amith Yamasanie43530a2009-08-21 13:11:37 -07004319 public void setNumSpeedSteps(int steps) {
4320 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
4321 }
4322
Amith Yamasanif37447b2009-10-08 18:28:01 -07004323 public void setRadioScanningTimeout(long timeout) {
4324 if (mPhoneSignalScanningTimer != null) {
4325 mPhoneSignalScanningTimer.setTimeout(timeout);
4326 }
4327 }
4328
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004329 @Override
4330 public boolean startIteratingOldHistoryLocked() {
4331 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4332 + " pos=" + mHistoryBuffer.dataPosition());
4333 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004334 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004335 mReadOverflow = false;
4336 mIteratingHistory = true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004337 return (mHistoryIterator = mHistory) != null;
4338 }
4339
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004340 @Override
4341 public boolean getNextOldHistoryLocked(HistoryItem out) {
4342 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
4343 if (!end) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004344 mHistoryReadTmp.readDelta(mHistoryBuffer);
4345 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004346 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004347 HistoryItem cur = mHistoryIterator;
4348 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004349 if (!mReadOverflow && !end) {
4350 Slog.w(TAG, "Old history ends before new history!");
4351 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004352 return false;
4353 }
4354 out.setTo(cur);
4355 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004356 if (!mReadOverflow) {
4357 if (end) {
4358 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004359 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004360 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
4361 PrintWriter pw = new PrintWriter(new LogWriter(android.util.Log.WARN, TAG));
4362 pw.println("Histories differ!");
4363 pw.println("Old history:");
4364 (new HistoryPrinter()).printNextItem(pw, out, now);
4365 pw.println("New history:");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004366 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004367 }
4368 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004369 return true;
4370 }
4371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004372 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004373 public void finishIteratingOldHistoryLocked() {
4374 mIteratingHistory = false;
4375 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
4376 }
4377
4378 @Override
4379 public boolean startIteratingHistoryLocked() {
4380 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4381 + " pos=" + mHistoryBuffer.dataPosition());
4382 mHistoryBuffer.setDataPosition(0);
4383 mReadOverflow = false;
4384 mIteratingHistory = true;
4385 return mHistoryBuffer.dataSize() > 0;
4386 }
4387
4388 @Override
4389 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004390 final int pos = mHistoryBuffer.dataPosition();
4391 if (pos == 0) {
4392 out.clear();
4393 }
4394 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004395 if (end) {
4396 return false;
4397 }
4398
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004399 out.readDelta(mHistoryBuffer);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004400 return true;
4401 }
4402
4403 @Override
4404 public void finishIteratingHistoryLocked() {
4405 mIteratingHistory = false;
4406 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004407 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004408
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004409 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004410 public long getHistoryBaseTime() {
4411 return mHistoryBaseTime;
4412 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004413
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004414 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415 public int getStartCount() {
4416 return mStartCount;
4417 }
4418
4419 public boolean isOnBattery() {
4420 return mOnBattery;
4421 }
4422
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004423 public boolean isScreenOn() {
4424 return mScreenOn;
4425 }
4426
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004427 void initTimes() {
4428 mBatteryRealtime = mTrackBatteryPastUptime = 0;
4429 mBatteryUptime = mTrackBatteryPastRealtime = 0;
4430 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4431 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4432 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4433 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
4434 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004435
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004436 void initDischarge() {
4437 mLowDischargeAmountSinceCharge = 0;
4438 mHighDischargeAmountSinceCharge = 0;
4439 mDischargeAmountScreenOn = 0;
4440 mDischargeAmountScreenOnSinceCharge = 0;
4441 mDischargeAmountScreenOff = 0;
4442 mDischargeAmountScreenOffSinceCharge = 0;
4443 }
4444
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004445 public void resetAllStatsLocked() {
4446 mStartCount = 0;
4447 initTimes();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004448 mScreenOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004449 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004450 mScreenBrightnessTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004451 }
4452 mInputEventCounter.reset(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004453 mPhoneOnTimer.reset(this, false);
4454 mAudioOnTimer.reset(this, false);
4455 mVideoOnTimer.reset(this, false);
Wink Saville52840902011-02-18 12:40:47 -08004456 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004457 mPhoneSignalStrengthsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004458 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004459 mPhoneSignalScanningTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004460 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004461 mPhoneDataConnectionsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004462 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004463 mWifiOnTimer.reset(this, false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004464 mGlobalWifiRunningTimer.reset(this, false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004465 mBluetoothOnTimer.reset(this, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004466
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004467 for (int i=0; i<mUidStats.size(); i++) {
4468 if (mUidStats.valueAt(i).reset()) {
4469 mUidStats.remove(mUidStats.keyAt(i));
4470 i--;
4471 }
4472 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004473
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004474 if (mKernelWakelockStats.size() > 0) {
4475 for (SamplingTimer timer : mKernelWakelockStats.values()) {
4476 mUnpluggables.remove(timer);
4477 }
4478 mKernelWakelockStats.clear();
4479 }
4480
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004481 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004482
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004483 clearHistoryLocked();
4484 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004485
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004486 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004487 if (oldScreenOn) {
4488 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
4489 if (diff > 0) {
4490 mDischargeAmountScreenOn += diff;
4491 mDischargeAmountScreenOnSinceCharge += diff;
4492 }
4493 } else {
4494 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
4495 if (diff > 0) {
4496 mDischargeAmountScreenOff += diff;
4497 mDischargeAmountScreenOffSinceCharge += diff;
4498 }
4499 }
4500 if (newScreenOn) {
4501 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
4502 mDischargeScreenOffUnplugLevel = 0;
4503 } else {
4504 mDischargeScreenOnUnplugLevel = 0;
4505 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
4506 }
4507 }
4508
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004509 void setOnBattery(boolean onBattery, int oldStatus, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 synchronized(this) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004511 setOnBatteryLocked(onBattery, oldStatus, level);
4512 }
4513 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004514
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004515 void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
4516 boolean doWrite = false;
4517 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
4518 m.arg1 = onBattery ? 1 : 0;
4519 mHandler.sendMessage(m);
4520 mOnBattery = mOnBatteryInternal = onBattery;
4521
4522 long uptime = SystemClock.uptimeMillis() * 1000;
4523 long mSecRealtime = SystemClock.elapsedRealtime();
4524 long realtime = mSecRealtime * 1000;
4525 if (onBattery) {
4526 // We will reset our status if we are unplugging after the
4527 // battery was last full, or the level is at 100, or
4528 // we have gone through a significant charge (from a very low
4529 // level to a now very high level).
4530 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
4531 || level >= 90
4532 || (mDischargeCurrentLevel < 20 && level >= 80)) {
4533 doWrite = true;
4534 resetAllStatsLocked();
4535 mDischargeStartLevel = level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004536 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004537 updateKernelWakelocksLocked();
4538 mHistoryCur.batteryLevel = (byte)level;
4539 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4540 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
4541 + Integer.toHexString(mHistoryCur.states));
4542 addHistoryRecordLocked(mSecRealtime);
4543 mTrackBatteryUptimeStart = uptime;
4544 mTrackBatteryRealtimeStart = realtime;
4545 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
4546 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
4547 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
4548 if (mScreenOn) {
4549 mDischargeScreenOnUnplugLevel = level;
4550 mDischargeScreenOffUnplugLevel = 0;
4551 } else {
4552 mDischargeScreenOnUnplugLevel = 0;
4553 mDischargeScreenOffUnplugLevel = level;
4554 }
4555 mDischargeAmountScreenOn = 0;
4556 mDischargeAmountScreenOff = 0;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004557 doUnplugLocked(realtime, mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004558 } else {
4559 updateKernelWakelocksLocked();
4560 mHistoryCur.batteryLevel = (byte)level;
4561 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4562 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
4563 + Integer.toHexString(mHistoryCur.states));
4564 addHistoryRecordLocked(mSecRealtime);
4565 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
4566 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
4567 mDischargeCurrentLevel = level;
4568 if (level < mDischargeUnplugLevel) {
4569 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
4570 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
4571 }
4572 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004573 doPlugLocked(realtime, getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004574 }
4575 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
4576 if (mFile != null) {
4577 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004578 }
4579 }
4580 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004581
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004582 // This should probably be exposed in the API, though it's not critical
4583 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004584
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004585 public void setBatteryState(int status, int health, int plugType, int level,
4586 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004587 synchronized(this) {
4588 boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
4589 int oldStatus = mHistoryCur.batteryStatus;
4590 if (!mHaveBatteryLevel) {
4591 mHaveBatteryLevel = true;
4592 // We start out assuming that the device is plugged in (not
4593 // on battery). If our first report is now that we are indeed
4594 // plugged in, then twiddle our state to correctly reflect that
4595 // since we won't be going through the full setOnBattery().
4596 if (onBattery == mOnBattery) {
4597 if (onBattery) {
4598 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4599 } else {
4600 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4601 }
4602 }
4603 oldStatus = status;
4604 }
4605 if (onBattery) {
4606 mDischargeCurrentLevel = level;
4607 mRecordingHistory = true;
4608 }
4609 if (onBattery != mOnBattery) {
4610 mHistoryCur.batteryLevel = (byte)level;
4611 mHistoryCur.batteryStatus = (byte)status;
4612 mHistoryCur.batteryHealth = (byte)health;
4613 mHistoryCur.batteryPlugType = (byte)plugType;
4614 mHistoryCur.batteryTemperature = (char)temp;
4615 mHistoryCur.batteryVoltage = (char)volt;
4616 setOnBatteryLocked(onBattery, oldStatus, level);
4617 } else {
4618 boolean changed = false;
4619 if (mHistoryCur.batteryLevel != level) {
4620 mHistoryCur.batteryLevel = (byte)level;
4621 changed = true;
4622 }
4623 if (mHistoryCur.batteryStatus != status) {
4624 mHistoryCur.batteryStatus = (byte)status;
4625 changed = true;
4626 }
4627 if (mHistoryCur.batteryHealth != health) {
4628 mHistoryCur.batteryHealth = (byte)health;
4629 changed = true;
4630 }
4631 if (mHistoryCur.batteryPlugType != plugType) {
4632 mHistoryCur.batteryPlugType = (byte)plugType;
4633 changed = true;
4634 }
4635 if (temp >= (mHistoryCur.batteryTemperature+10)
4636 || temp <= (mHistoryCur.batteryTemperature-10)) {
4637 mHistoryCur.batteryTemperature = (char)temp;
4638 changed = true;
4639 }
4640 if (volt > (mHistoryCur.batteryVoltage+20)
4641 || volt < (mHistoryCur.batteryVoltage-20)) {
4642 mHistoryCur.batteryVoltage = (char)volt;
4643 changed = true;
4644 }
4645 if (changed) {
4646 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004647 }
4648 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004649 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
4650 // We don't record history while we are plugged in and fully charged.
4651 // The next time we are unplugged, history will be cleared.
4652 mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004653 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004654 }
Evan Millar633a1742009-04-02 16:36:33 -07004655 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004656
Evan Millarc64edde2009-04-18 12:26:32 -07004657 public void updateKernelWakelocksLocked() {
4658 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004659
Marco Nelissend8593312009-04-30 14:45:06 -07004660 if (m == null) {
4661 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004662 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07004663 return;
4664 }
4665
Evan Millarc64edde2009-04-18 12:26:32 -07004666 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
4667 String name = ent.getKey();
4668 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004669
Evan Millarc64edde2009-04-18 12:26:32 -07004670 SamplingTimer kwlt = mKernelWakelockStats.get(name);
4671 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004672 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07004673 true /* track reported values */);
4674 mKernelWakelockStats.put(name, kwlt);
4675 }
4676 kwlt.updateCurrentReportedCount(kws.mCount);
4677 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
4678 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
4679 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004680
Evan Millarc64edde2009-04-18 12:26:32 -07004681 if (m.size() != mKernelWakelockStats.size()) {
4682 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
4683 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4684 SamplingTimer st = ent.getValue();
4685 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
4686 st.setStale();
4687 }
4688 }
4689 }
4690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004691
4692 public long getAwakeTimeBattery() {
4693 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
4694 }
4695
4696 public long getAwakeTimePlugged() {
4697 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
4698 }
4699
4700 @Override
4701 public long computeUptime(long curTime, int which) {
4702 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004703 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004704 case STATS_LAST: return mLastUptime;
4705 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004706 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004707 }
4708 return 0;
4709 }
4710
4711 @Override
4712 public long computeRealtime(long curTime, int which) {
4713 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004714 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004715 case STATS_LAST: return mLastRealtime;
4716 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004717 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004718 }
4719 return 0;
4720 }
4721
4722 @Override
4723 public long computeBatteryUptime(long curTime, int which) {
4724 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004725 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004726 return mBatteryUptime + getBatteryUptime(curTime);
4727 case STATS_LAST:
4728 return mBatteryLastUptime;
4729 case STATS_CURRENT:
4730 return getBatteryUptime(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004731 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004732 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
4733 }
4734 return 0;
4735 }
4736
4737 @Override
4738 public long computeBatteryRealtime(long curTime, int which) {
4739 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004740 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
4742 case STATS_LAST:
4743 return mBatteryLastRealtime;
4744 case STATS_CURRENT:
4745 return getBatteryRealtimeLocked(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004746 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004747 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
4748 }
4749 return 0;
4750 }
4751
4752 long getBatteryUptimeLocked(long curTime) {
4753 long time = mTrackBatteryPastUptime;
4754 if (mOnBatteryInternal) {
4755 time += curTime - mTrackBatteryUptimeStart;
4756 }
4757 return time;
4758 }
4759
4760 long getBatteryUptimeLocked() {
4761 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
4762 }
4763
4764 @Override
4765 public long getBatteryUptime(long curTime) {
4766 return getBatteryUptimeLocked(curTime);
4767 }
4768
4769 long getBatteryRealtimeLocked(long curTime) {
4770 long time = mTrackBatteryPastRealtime;
4771 if (mOnBatteryInternal) {
4772 time += curTime - mTrackBatteryRealtimeStart;
4773 }
4774 return time;
4775 }
4776
4777 @Override
4778 public long getBatteryRealtime(long curTime) {
4779 return getBatteryRealtimeLocked(curTime);
4780 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004781
4782 private long getTcpBytes(long current, long[] dataBytes, int which) {
4783 if (which == STATS_LAST) {
4784 return dataBytes[STATS_LAST];
4785 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004786 if (which == STATS_SINCE_UNPLUGGED) {
4787 if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004788 return dataBytes[STATS_LAST];
4789 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004790 return current - dataBytes[STATS_SINCE_UNPLUGGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004791 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004792 } else if (which == STATS_SINCE_CHARGED) {
4793 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004794 }
4795 return current - dataBytes[STATS_CURRENT];
4796 }
4797 }
4798
4799 /** Only STATS_UNPLUGGED works properly */
4800 public long getMobileTcpBytesSent(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004801 final long mobileTxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).txBytes;
4802 return getTcpBytes(mobileTxBytes, mMobileDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004803 }
4804
4805 /** Only STATS_UNPLUGGED works properly */
4806 public long getMobileTcpBytesReceived(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004807 final long mobileRxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).rxBytes;
4808 return getTcpBytes(mobileRxBytes, mMobileDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004809 }
4810
4811 /** Only STATS_UNPLUGGED works properly */
4812 public long getTotalTcpBytesSent(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004813 final long totalTxBytes = getNetworkStatsSummary().getTotal(null).txBytes;
4814 return getTcpBytes(totalTxBytes, mTotalDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004815 }
4816
4817 /** Only STATS_UNPLUGGED works properly */
4818 public long getTotalTcpBytesReceived(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004819 final long totalRxBytes = getNetworkStatsSummary().getTotal(null).rxBytes;
4820 return getTcpBytes(totalRxBytes, mTotalDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004821 }
4822
The Android Open Source Project10592532009-03-18 17:39:46 -07004823 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004824 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004825 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004826 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004827 }
4828 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004829
Evan Millar633a1742009-04-02 16:36:33 -07004830 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004831 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004832 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004833
The Android Open Source Project10592532009-03-18 17:39:46 -07004834 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004835 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004836 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004837 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004838 }
4839 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004840
Evan Millar633a1742009-04-02 16:36:33 -07004841 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004842 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004843 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844
Amith Yamasanie43530a2009-08-21 13:11:37 -07004845 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004846 public int getLowDischargeAmountSinceCharge() {
4847 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004848 int val = mLowDischargeAmountSinceCharge;
4849 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4850 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
4851 }
4852 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004853 }
4854 }
4855
4856 @Override
4857 public int getHighDischargeAmountSinceCharge() {
4858 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004859 int val = mHighDischargeAmountSinceCharge;
4860 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4861 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
4862 }
4863 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004864 }
4865 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004866
4867 public int getDischargeAmountScreenOn() {
4868 synchronized(this) {
4869 int val = mDischargeAmountScreenOn;
4870 if (mOnBattery && mScreenOn
4871 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4872 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4873 }
4874 return val;
4875 }
4876 }
4877
4878 public int getDischargeAmountScreenOnSinceCharge() {
4879 synchronized(this) {
4880 int val = mDischargeAmountScreenOnSinceCharge;
4881 if (mOnBattery && mScreenOn
4882 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4883 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4884 }
4885 return val;
4886 }
4887 }
4888
4889 public int getDischargeAmountScreenOff() {
4890 synchronized(this) {
4891 int val = mDischargeAmountScreenOff;
4892 if (mOnBattery && !mScreenOn
4893 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4894 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4895 }
4896 return val;
4897 }
4898 }
4899
4900 public int getDischargeAmountScreenOffSinceCharge() {
4901 synchronized(this) {
4902 int val = mDischargeAmountScreenOffSinceCharge;
4903 if (mOnBattery && !mScreenOn
4904 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4905 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4906 }
4907 return val;
4908 }
4909 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004910
4911 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07004912 public int getCpuSpeedSteps() {
4913 return sNumSpeedSteps;
4914 }
4915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916 /**
4917 * Retrieve the statistics object for a particular uid, creating if needed.
4918 */
4919 public Uid getUidStatsLocked(int uid) {
4920 Uid u = mUidStats.get(uid);
4921 if (u == null) {
4922 u = new Uid(uid);
4923 mUidStats.put(uid, u);
4924 }
4925 return u;
4926 }
4927
4928 /**
4929 * Remove the statistics object for a particular uid.
4930 */
4931 public void removeUidStatsLocked(int uid) {
4932 mUidStats.remove(uid);
4933 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004935 /**
4936 * Retrieve the statistics object for a particular process, creating
4937 * if needed.
4938 */
4939 public Uid.Proc getProcessStatsLocked(int uid, String name) {
4940 Uid u = getUidStatsLocked(uid);
4941 return u.getProcessStatsLocked(name);
4942 }
4943
4944 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004945 * Retrieve the statistics object for a particular process, given
4946 * the name of the process.
4947 * @param name process name
4948 * @return the statistics object for the process
4949 */
Amith Yamasani819f9282009-06-24 23:18:15 -07004950 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004951 int uid;
4952 if (mUidCache.containsKey(name)) {
4953 uid = mUidCache.get(name);
4954 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07004955 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004956 mUidCache.put(name, uid);
4957 }
4958 Uid u = getUidStatsLocked(uid);
4959 return u.getProcessStatsLocked(name);
4960 }
4961
4962 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963 * Retrieve the statistics object for a particular process, creating
4964 * if needed.
4965 */
4966 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
4967 Uid u = getUidStatsLocked(uid);
4968 return u.getPackageStatsLocked(pkg);
4969 }
4970
4971 /**
4972 * Retrieve the statistics object for a particular service, creating
4973 * if needed.
4974 */
4975 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
4976 Uid u = getUidStatsLocked(uid);
4977 return u.getServiceStatsLocked(pkg, name);
4978 }
4979
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004980 /**
4981 * Massage data to distribute any reasonable work down to more specific
4982 * owners. Must only be called on a dead BatteryStats object!
4983 */
4984 public void distributeWorkLocked(int which) {
4985 // Aggregate all CPU time associated with WIFI.
4986 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
4987 if (wifiUid != null) {
4988 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
4989 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
4990 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
4991 for (int i=0; i<mUidStats.size(); i++) {
4992 Uid uid = mUidStats.valueAt(i);
4993 if (uid.mUid != Process.WIFI_UID) {
4994 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
4995 if (uidRunningTime > 0) {
4996 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
4997 long time = proc.getUserTime(which);
4998 time = (time*uidRunningTime)/totalRunningTime;
4999 uidProc.mUserTime += time;
5000 proc.mUserTime -= time;
5001 time = proc.getSystemTime(which);
5002 time = (time*uidRunningTime)/totalRunningTime;
5003 uidProc.mSystemTime += time;
5004 proc.mSystemTime -= time;
5005 time = proc.getForegroundTime(which);
5006 time = (time*uidRunningTime)/totalRunningTime;
5007 uidProc.mForegroundTime += time;
5008 proc.mForegroundTime -= time;
5009 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
5010 SamplingCounter sc = proc.mSpeedBins[sb];
5011 if (sc != null) {
5012 time = sc.getCountLocked(which);
5013 time = (time*uidRunningTime)/totalRunningTime;
5014 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
5015 if (uidSc == null) {
5016 uidSc = new SamplingCounter(mUnpluggables);
5017 uidProc.mSpeedBins[sb] = uidSc;
5018 }
5019 uidSc.mCount.addAndGet((int)time);
5020 sc.mCount.addAndGet((int)-time);
5021 }
5022 }
5023 totalRunningTime -= uidRunningTime;
5024 }
5025 }
5026 }
5027 }
5028 }
5029 }
5030
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005031 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005032 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005033 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005034 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005035
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005036 Parcel mPendingWrite = null;
5037 final ReentrantLock mWriteLock = new ReentrantLock();
5038
5039 public void writeAsyncLocked() {
5040 writeLocked(false);
5041 }
5042
5043 public void writeSyncLocked() {
5044 writeLocked(true);
5045 }
5046
5047 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005048 if (mFile == null) {
5049 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005050 return;
5051 }
5052
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005053 if (mShuttingDown) {
5054 return;
5055 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005056
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005057 Parcel out = Parcel.obtain();
5058 writeSummaryToParcel(out);
5059 mLastWriteTime = SystemClock.elapsedRealtime();
5060
5061 if (mPendingWrite != null) {
5062 mPendingWrite.recycle();
5063 }
5064 mPendingWrite = out;
5065
5066 if (sync) {
5067 commitPendingDataToDisk();
5068 } else {
5069 Thread thr = new Thread("BatteryStats-Write") {
5070 @Override
5071 public void run() {
5072 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5073 commitPendingDataToDisk();
5074 }
5075 };
5076 thr.start();
5077 }
5078 }
5079
5080 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07005081 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005082 synchronized (this) {
5083 next = mPendingWrite;
5084 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07005085 if (next == null) {
5086 return;
5087 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005088
5089 mWriteLock.lock();
5090 }
5091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005092 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005093 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005094 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005095 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07005096 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005097 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005098 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005099 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005100 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005101 mFile.rollback();
5102 } finally {
5103 next.recycle();
5104 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07005105 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005106 }
5107
5108 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
5109 int pos = 0;
5110 int avail = stream.available();
5111 byte[] data = new byte[avail];
5112 while (true) {
5113 int amt = stream.read(data, pos, data.length-pos);
5114 //Log.i("foo", "Read " + amt + " bytes at " + pos
5115 // + " of avail " + data.length);
5116 if (amt <= 0) {
5117 //Log.i("foo", "**** FINISHED READING: pos=" + pos
5118 // + " len=" + data.length);
5119 return data;
5120 }
5121 pos += amt;
5122 avail = stream.available();
5123 if (avail > data.length-pos) {
5124 byte[] newData = new byte[pos+avail];
5125 System.arraycopy(data, 0, newData, 0, pos);
5126 data = newData;
5127 }
5128 }
5129 }
5130
5131 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005132 if (mFile == null) {
5133 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005134 return;
5135 }
5136
5137 mUidStats.clear();
5138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005139 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005140 File file = mFile.chooseForRead();
5141 if (!file.exists()) {
5142 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005143 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005144 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005145
5146 byte[] raw = readFully(stream);
5147 Parcel in = Parcel.obtain();
5148 in.unmarshall(raw, 0, raw.length);
5149 in.setDataPosition(0);
5150 stream.close();
5151
5152 readSummaryFromParcel(in);
5153 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005154 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005155 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005156
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005157 long now = SystemClock.elapsedRealtime();
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005158 if (USE_OLD_HISTORY) {
5159 addHistoryRecordLocked(now, HistoryItem.CMD_START);
5160 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005161 addHistoryBufferLocked(now, HistoryItem.CMD_START);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005162 }
5163
5164 public int describeContents() {
5165 return 0;
5166 }
5167
Dianne Hackbornae384452011-06-28 12:33:48 -07005168 void readHistory(Parcel in, boolean andOldHistory) {
5169 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005170
5171 mHistoryBuffer.setDataSize(0);
5172 mHistoryBuffer.setDataPosition(0);
5173
5174 int bufSize = in.readInt();
5175 int curPos = in.dataPosition();
5176 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
5177 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
5178 } else if ((bufSize&~3) != bufSize) {
5179 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
5180 } else {
5181 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
5182 + " bytes at " + curPos);
5183 mHistoryBuffer.appendFrom(in, curPos, bufSize);
5184 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005185 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005186
Dianne Hackbornae384452011-06-28 12:33:48 -07005187 if (andOldHistory) {
5188 readOldHistory(in);
5189 }
5190
5191 if (DEBUG_HISTORY) {
5192 StringBuilder sb = new StringBuilder(128);
5193 sb.append("****************** OLD mHistoryBaseTime: ");
5194 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5195 Slog.i(TAG, sb.toString());
5196 }
5197 mHistoryBaseTime = historyBaseTime;
5198 if (DEBUG_HISTORY) {
5199 StringBuilder sb = new StringBuilder(128);
5200 sb.append("****************** NEW mHistoryBaseTime: ");
5201 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5202 Slog.i(TAG, sb.toString());
5203 }
5204
5205 // We are just arbitrarily going to insert 1 minute from the sample of
5206 // the last run until samples in this run.
5207 if (mHistoryBaseTime > 0) {
5208 long oldnow = SystemClock.elapsedRealtime();
5209 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000;
5210 if (DEBUG_HISTORY) {
5211 StringBuilder sb = new StringBuilder(128);
5212 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
5213 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5214 Slog.i(TAG, sb.toString());
5215 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07005216 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005217 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005218
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005219 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005220 if (!USE_OLD_HISTORY) {
5221 return;
5222 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005223 mHistory = mHistoryEnd = mHistoryCache = null;
5224 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07005225 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005226 HistoryItem rec = new HistoryItem(time, in);
5227 addHistoryRecordLocked(rec);
5228 }
5229 }
5230
Dianne Hackbornae384452011-06-28 12:33:48 -07005231 void writeHistory(Parcel out, boolean andOldHistory) {
5232 if (DEBUG_HISTORY) {
5233 StringBuilder sb = new StringBuilder(128);
5234 sb.append("****************** WRITING mHistoryBaseTime: ");
5235 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5236 sb.append(" mLastHistoryTime: ");
5237 TimeUtils.formatDuration(mLastHistoryTime, sb);
5238 Slog.i(TAG, sb.toString());
5239 }
5240 out.writeLong(mHistoryBaseTime + mLastHistoryTime);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005241 out.writeInt(mHistoryBuffer.dataSize());
5242 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
5243 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
5244 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07005245
5246 if (andOldHistory) {
5247 writeOldHistory(out);
5248 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005249 }
5250
5251 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005252 if (!USE_OLD_HISTORY) {
5253 return;
5254 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005255 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005256 while (rec != null) {
5257 if (rec.time >= 0) rec.writeToParcel(out, 0);
5258 rec = rec.next;
5259 }
5260 out.writeLong(-1);
5261 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005263 private void readSummaryFromParcel(Parcel in) {
5264 final int version = in.readInt();
5265 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005266 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005267 + ", expected " + VERSION + "; erasing old stats");
5268 return;
5269 }
5270
Dianne Hackbornae384452011-06-28 12:33:48 -07005271 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005273 mStartCount = in.readInt();
5274 mBatteryUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005275 mBatteryRealtime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005277 mRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005278 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005279 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005280 mLowDischargeAmountSinceCharge = in.readInt();
5281 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005282 mDischargeAmountScreenOnSinceCharge = in.readInt();
5283 mDischargeAmountScreenOffSinceCharge = in.readInt();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005285 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287 mScreenOn = false;
5288 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005289 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5290 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
5291 }
5292 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005293 mPhoneOn = false;
5294 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08005295 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005296 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
5297 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005298 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005299 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5300 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
5301 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005302 mWifiOn = false;
5303 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005304 mGlobalWifiRunning = false;
5305 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005306 mBluetoothOn = false;
5307 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005308
Evan Millarc64edde2009-04-18 12:26:32 -07005309 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005310 if (NKW > 10000) {
5311 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
5312 return;
5313 }
Evan Millarc64edde2009-04-18 12:26:32 -07005314 for (int ikw = 0; ikw < NKW; ikw++) {
5315 if (in.readInt() != 0) {
5316 String kwltName = in.readString();
5317 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
5318 }
5319 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005320
5321 sNumSpeedSteps = in.readInt();
5322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005323 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005324 if (NU > 10000) {
5325 Slog.w(TAG, "File corrupt: too many uids " + NU);
5326 return;
5327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005328 for (int iu = 0; iu < NU; iu++) {
5329 int uid = in.readInt();
5330 Uid u = new Uid(uid);
5331 mUidStats.put(uid, u);
5332
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005333 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005334 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005335 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005336 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005337 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005338 if (in.readInt() != 0) {
5339 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
5340 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005341 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005342 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005343 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005344 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005345 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005346 if (in.readInt() != 0) {
5347 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
5348 }
5349 u.mAudioTurnedOn = false;
5350 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005351 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005352 }
5353 u.mVideoTurnedOn = false;
5354 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005355 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
5356 }
5357 if (in.readInt() != 0) {
5358 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005359 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005360
Dianne Hackborn617f8772009-03-31 15:04:46 -07005361 if (in.readInt() != 0) {
5362 if (u.mUserActivityCounters == null) {
5363 u.initUserActivityLocked();
5364 }
5365 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5366 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
5367 }
5368 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005370 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005371 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005372 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
5373 return;
5374 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005375 for (int iw = 0; iw < NW; iw++) {
5376 String wlName = in.readString();
5377 if (in.readInt() != 0) {
5378 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
5379 }
5380 if (in.readInt() != 0) {
5381 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
5382 }
5383 if (in.readInt() != 0) {
5384 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
5385 }
5386 }
5387
5388 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005389 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005390 Slog.w(TAG, "File corrupt: too many sensors " + NP);
5391 return;
5392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005393 for (int is = 0; is < NP; is++) {
5394 int seNumber = in.readInt();
5395 if (in.readInt() != 0) {
5396 u.getSensorTimerLocked(seNumber, true)
5397 .readSummaryFromParcelLocked(in);
5398 }
5399 }
5400
5401 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005402 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005403 Slog.w(TAG, "File corrupt: too many processes " + NP);
5404 return;
5405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005406 for (int ip = 0; ip < NP; ip++) {
5407 String procName = in.readString();
5408 Uid.Proc p = u.getProcessStatsLocked(procName);
5409 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005411 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005412 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005413 if (NSB > 100) {
5414 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
5415 return;
5416 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005417 p.mSpeedBins = new SamplingCounter[NSB];
5418 for (int i=0; i<NSB; i++) {
5419 if (in.readInt() != 0) {
5420 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables);
5421 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
5422 }
5423 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005424 if (!p.readExcessivePowerFromParcelLocked(in)) {
5425 return;
5426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005427 }
5428
5429 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005430 if (NP > 10000) {
5431 Slog.w(TAG, "File corrupt: too many packages " + NP);
5432 return;
5433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005434 for (int ip = 0; ip < NP; ip++) {
5435 String pkgName = in.readString();
5436 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
5437 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005438 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005439 if (NS > 1000) {
5440 Slog.w(TAG, "File corrupt: too many services " + NS);
5441 return;
5442 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005443 for (int is = 0; is < NS; is++) {
5444 String servName = in.readString();
5445 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
5446 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005447 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005448 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005449 }
5450 }
5451
5452 u.mLoadedTcpBytesReceived = in.readLong();
5453 u.mLoadedTcpBytesSent = in.readLong();
5454 }
5455 }
5456
5457 /**
5458 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
5459 * disk. This format does not allow a lossless round-trip.
5460 *
5461 * @param out the Parcel to be written to.
5462 */
5463 public void writeSummaryToParcel(Parcel out) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005464 // Need to update with current kernel wake lock counts.
5465 updateKernelWakelocksLocked();
5466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005467 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
5468 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
5469 final long NOW = getBatteryUptimeLocked(NOW_SYS);
5470 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
5471
5472 out.writeInt(VERSION);
5473
Dianne Hackbornae384452011-06-28 12:33:48 -07005474 writeHistory(out, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005476 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005477 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005478 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005479 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005480 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005481 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005482 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08005483 out.writeInt(getLowDischargeAmountSinceCharge());
5484 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005485 out.writeInt(getDischargeAmountScreenOnSinceCharge());
5486 out.writeInt(getDischargeAmountScreenOffSinceCharge());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005487
5488 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005489 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5490 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5491 }
5492 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005493 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Wink Saville52840902011-02-18 12:40:47 -08005494 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005495 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5496 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005497 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005498 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5499 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5500 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005501 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005502 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07005503 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005504
Evan Millarc64edde2009-04-18 12:26:32 -07005505 out.writeInt(mKernelWakelockStats.size());
5506 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5507 Timer kwlt = ent.getValue();
5508 if (kwlt != null) {
5509 out.writeInt(1);
5510 out.writeString(ent.getKey());
5511 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
5512 } else {
5513 out.writeInt(0);
5514 }
5515 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005516
Amith Yamasanie43530a2009-08-21 13:11:37 -07005517 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 final int NU = mUidStats.size();
5519 out.writeInt(NU);
5520 for (int iu = 0; iu < NU; iu++) {
5521 out.writeInt(mUidStats.keyAt(iu));
5522 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005523
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005524 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005525 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005526 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005527 } else {
5528 out.writeInt(0);
5529 }
5530 if (u.mFullWifiLockTimer != null) {
5531 out.writeInt(1);
5532 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5533 } else {
5534 out.writeInt(0);
5535 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005536 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005537 out.writeInt(1);
Nick Pelly6ccaa542012-06-15 15:22:47 -07005538 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005539 } else {
5540 out.writeInt(0);
5541 }
5542 if (u.mWifiMulticastTimer != null) {
5543 out.writeInt(1);
5544 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5545 } else {
5546 out.writeInt(0);
5547 }
5548 if (u.mAudioTurnedOnTimer != null) {
5549 out.writeInt(1);
5550 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5551 } else {
5552 out.writeInt(0);
5553 }
5554 if (u.mVideoTurnedOnTimer != null) {
5555 out.writeInt(1);
5556 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5557 } else {
5558 out.writeInt(0);
5559 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005560 if (u.mVibratorOnTimer != null) {
5561 out.writeInt(1);
5562 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5563 } else {
5564 out.writeInt(0);
5565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005566
Dianne Hackborn617f8772009-03-31 15:04:46 -07005567 if (u.mUserActivityCounters == null) {
5568 out.writeInt(0);
5569 } else {
5570 out.writeInt(1);
5571 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5572 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
5573 }
5574 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005576 int NW = u.mWakelockStats.size();
5577 out.writeInt(NW);
5578 if (NW > 0) {
5579 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
5580 : u.mWakelockStats.entrySet()) {
5581 out.writeString(ent.getKey());
5582 Uid.Wakelock wl = ent.getValue();
5583 if (wl.mTimerFull != null) {
5584 out.writeInt(1);
5585 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
5586 } else {
5587 out.writeInt(0);
5588 }
5589 if (wl.mTimerPartial != null) {
5590 out.writeInt(1);
5591 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
5592 } else {
5593 out.writeInt(0);
5594 }
5595 if (wl.mTimerWindow != null) {
5596 out.writeInt(1);
5597 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
5598 } else {
5599 out.writeInt(0);
5600 }
5601 }
5602 }
5603
5604 int NSE = u.mSensorStats.size();
5605 out.writeInt(NSE);
5606 if (NSE > 0) {
5607 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
5608 : u.mSensorStats.entrySet()) {
5609 out.writeInt(ent.getKey());
5610 Uid.Sensor se = ent.getValue();
5611 if (se.mTimer != null) {
5612 out.writeInt(1);
5613 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5614 } else {
5615 out.writeInt(0);
5616 }
5617 }
5618 }
5619
5620 int NP = u.mProcessStats.size();
5621 out.writeInt(NP);
5622 if (NP > 0) {
5623 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
5624 : u.mProcessStats.entrySet()) {
5625 out.writeString(ent.getKey());
5626 Uid.Proc ps = ent.getValue();
5627 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005628 out.writeLong(ps.mSystemTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005629 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005630 final int N = ps.mSpeedBins.length;
5631 out.writeInt(N);
5632 for (int i=0; i<N; i++) {
5633 if (ps.mSpeedBins[i] != null) {
5634 out.writeInt(1);
5635 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
5636 } else {
5637 out.writeInt(0);
5638 }
5639 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005640 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005641 }
5642 }
5643
5644 NP = u.mPackageStats.size();
5645 out.writeInt(NP);
5646 if (NP > 0) {
5647 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
5648 : u.mPackageStats.entrySet()) {
5649 out.writeString(ent.getKey());
5650 Uid.Pkg ps = ent.getValue();
5651 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005652 final int NS = ps.mServiceStats.size();
5653 out.writeInt(NS);
5654 if (NS > 0) {
5655 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
5656 : ps.mServiceStats.entrySet()) {
5657 out.writeString(sent.getKey());
5658 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
5659 long time = ss.getStartTimeToNowLocked(NOW);
5660 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005661 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005662 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005663 }
5664 }
5665 }
5666 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005667
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005668 out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED));
5669 out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005670 }
5671 }
5672
5673 public void readFromParcel(Parcel in) {
5674 readFromParcelLocked(in);
5675 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005677 void readFromParcelLocked(Parcel in) {
5678 int magic = in.readInt();
5679 if (magic != MAGIC) {
5680 throw new ParcelFormatException("Bad magic number");
5681 }
5682
Dianne Hackbornae384452011-06-28 12:33:48 -07005683 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005685 mStartCount = in.readInt();
5686 mBatteryUptime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005687 mBatteryLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005688 mBatteryRealtime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005689 mBatteryLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005690 mScreenOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005691 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005692 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005693 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i,
5694 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005695 }
5696 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 mPhoneOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005698 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Wink Saville52840902011-02-18 12:40:47 -08005699 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005700 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
5701 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005702 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005703 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005704 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005705 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
5706 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005707 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005708 mWifiOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005709 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005710 mGlobalWifiRunning = false;
5711 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005712 mBluetoothOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005713 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005714 mUptime = in.readLong();
5715 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005716 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005717 mRealtime = in.readLong();
5718 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005719 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005720 mOnBattery = in.readInt() != 0;
5721 mOnBatteryInternal = false; // we are no longer really running.
5722 mTrackBatteryPastUptime = in.readLong();
5723 mTrackBatteryUptimeStart = in.readLong();
5724 mTrackBatteryPastRealtime = in.readLong();
5725 mTrackBatteryRealtimeStart = in.readLong();
5726 mUnpluggedBatteryUptime = in.readLong();
5727 mUnpluggedBatteryRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005728 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005729 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005730 mLowDischargeAmountSinceCharge = in.readInt();
5731 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005732 mDischargeAmountScreenOn = in.readInt();
5733 mDischargeAmountScreenOnSinceCharge = in.readInt();
5734 mDischargeAmountScreenOff = in.readInt();
5735 mDischargeAmountScreenOffSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005736 mLastWriteTime = in.readLong();
5737
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005738 mMobileDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005739 mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005740 mMobileDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005741 mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005742 mTotalDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005743 mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005744 mTotalDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005745 mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005746
5747 mRadioDataUptime = in.readLong();
5748 mRadioDataStart = -1;
5749
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005750 mBluetoothPingCount = in.readInt();
5751 mBluetoothPingStart = -1;
5752
Evan Millarc64edde2009-04-18 12:26:32 -07005753 mKernelWakelockStats.clear();
5754 int NKW = in.readInt();
5755 for (int ikw = 0; ikw < NKW; ikw++) {
5756 if (in.readInt() != 0) {
5757 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005758 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07005759 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
5760 mKernelWakelockStats.put(wakelockName, kwlt);
5761 }
5762 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005764 mPartialTimers.clear();
5765 mFullTimers.clear();
5766 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005767 mWifiRunningTimers.clear();
5768 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -07005769 mWifiScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005770 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005771
Amith Yamasanie43530a2009-08-21 13:11:37 -07005772 sNumSpeedSteps = in.readInt();
5773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 int numUids = in.readInt();
5775 mUidStats.clear();
5776 for (int i = 0; i < numUids; i++) {
5777 int uid = in.readInt();
5778 Uid u = new Uid(uid);
5779 u.readFromParcelLocked(mUnpluggables, in);
5780 mUidStats.append(uid, u);
5781 }
5782 }
5783
5784 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005785 writeToParcelLocked(out, true, flags);
5786 }
5787
5788 public void writeToParcelWithoutUids(Parcel out, int flags) {
5789 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005791
5792 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005793 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005794 // Need to update with current kernel wake lock counts.
5795 updateKernelWakelocksLocked();
5796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005797 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
5798 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
5799 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
5800 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005802 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005803
Dianne Hackbornae384452011-06-28 12:33:48 -07005804 writeHistory(out, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005806 out.writeInt(mStartCount);
5807 out.writeLong(mBatteryUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005808 out.writeLong(mBatteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005809 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005810 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5811 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
5812 }
5813 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005814 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Wink Saville52840902011-02-18 12:40:47 -08005815 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005816 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
5817 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005818 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005819 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5820 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
5821 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005822 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005823 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005824 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005825 out.writeLong(mUptime);
5826 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005827 out.writeLong(mRealtime);
5828 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005829 out.writeInt(mOnBattery ? 1 : 0);
5830 out.writeLong(batteryUptime);
5831 out.writeLong(mTrackBatteryUptimeStart);
5832 out.writeLong(batteryRealtime);
5833 out.writeLong(mTrackBatteryRealtimeStart);
5834 out.writeLong(mUnpluggedBatteryUptime);
5835 out.writeLong(mUnpluggedBatteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005836 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005837 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005838 out.writeInt(mLowDischargeAmountSinceCharge);
5839 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005840 out.writeInt(mDischargeAmountScreenOn);
5841 out.writeInt(mDischargeAmountScreenOnSinceCharge);
5842 out.writeInt(mDischargeAmountScreenOff);
5843 out.writeInt(mDischargeAmountScreenOffSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005844 out.writeLong(mLastWriteTime);
5845
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005846 out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5847 out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED));
5848 out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5849 out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED));
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005850
5851 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005852 out.writeLong(getRadioDataUptime());
5853
5854 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005855
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005856 if (inclUids) {
5857 out.writeInt(mKernelWakelockStats.size());
5858 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5859 SamplingTimer kwlt = ent.getValue();
5860 if (kwlt != null) {
5861 out.writeInt(1);
5862 out.writeString(ent.getKey());
5863 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
5864 } else {
5865 out.writeInt(0);
5866 }
Evan Millarc64edde2009-04-18 12:26:32 -07005867 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005868 } else {
5869 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07005870 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005871
5872 out.writeInt(sNumSpeedSteps);
5873
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005874 if (inclUids) {
5875 int size = mUidStats.size();
5876 out.writeInt(size);
5877 for (int i = 0; i < size; i++) {
5878 out.writeInt(mUidStats.keyAt(i));
5879 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005880
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005881 uid.writeToParcelLocked(out, batteryRealtime);
5882 }
5883 } else {
5884 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005885 }
5886 }
5887
5888 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
5889 new Parcelable.Creator<BatteryStatsImpl>() {
5890 public BatteryStatsImpl createFromParcel(Parcel in) {
5891 return new BatteryStatsImpl(in);
5892 }
5893
5894 public BatteryStatsImpl[] newArray(int size) {
5895 return new BatteryStatsImpl[size];
5896 }
5897 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005898
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005899 public void prepareForDumpLocked() {
5900 // Need to retrieve current kernel wake lock stats before printing.
5901 updateKernelWakelocksLocked();
5902 }
5903
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005904 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005905 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005906 Printer pr = new PrintWriterPrinter(pw);
5907 pr.println("*** Screen timer:");
5908 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005909 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005910 pr.println("*** Screen brightness #" + i + ":");
5911 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005912 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005913 pr.println("*** Input event counter:");
5914 mInputEventCounter.logState(pr, " ");
5915 pr.println("*** Phone timer:");
5916 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08005917 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005918 pr.println("*** Signal strength #" + i + ":");
5919 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005920 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005921 pr.println("*** Signal scanning :");
5922 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005923 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005924 pr.println("*** Data connection type #" + i + ":");
5925 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005926 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005927 pr.println("*** Wifi timer:");
5928 mWifiOnTimer.logState(pr, " ");
5929 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005930 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005931 pr.println("*** Bluetooth timer:");
5932 mBluetoothOnTimer.logState(pr, " ");
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005933 pr.println("*** Mobile ifaces:");
5934 pr.println(mMobileIfaces.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005935 }
5936 super.dumpLocked(pw);
5937 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005938
5939 private NetworkStats mNetworkSummaryCache;
5940 private NetworkStats mNetworkDetailCache;
5941
5942 private NetworkStats getNetworkStatsSummary() {
5943 // NOTE: calls from BatteryStatsService already hold this lock
5944 synchronized (this) {
5945 if (mNetworkSummaryCache == null
5946 || mNetworkSummaryCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) {
Jeff Sharkey418d12d2011-12-13 15:38:03 -08005947 mNetworkSummaryCache = null;
5948
5949 if (SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) {
5950 try {
Jeff Sharkeye8914c32012-05-01 16:26:09 -07005951 mNetworkSummaryCache = mNetworkStatsFactory.readNetworkStatsSummaryDev();
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08005952 } catch (IOException e) {
Jeff Sharkey418d12d2011-12-13 15:38:03 -08005953 Log.wtf(TAG, "problem reading network stats", e);
5954 }
5955 }
5956
5957 if (mNetworkSummaryCache == null) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005958 mNetworkSummaryCache = new NetworkStats(SystemClock.elapsedRealtime(), 0);
5959 }
5960 }
5961 return mNetworkSummaryCache;
5962 }
5963 }
5964
5965 private NetworkStats getNetworkStatsDetailGroupedByUid() {
5966 // NOTE: calls from BatteryStatsService already hold this lock
5967 synchronized (this) {
5968 if (mNetworkDetailCache == null
5969 || mNetworkDetailCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) {
Jeff Sharkey418d12d2011-12-13 15:38:03 -08005970 mNetworkDetailCache = null;
5971
5972 if (SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) {
5973 try {
5974 mNetworkDetailCache = mNetworkStatsFactory
5975 .readNetworkStatsDetail().groupedByUid();
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08005976 } catch (IOException e) {
Jeff Sharkey418d12d2011-12-13 15:38:03 -08005977 Log.wtf(TAG, "problem reading network stats", e);
5978 }
5979 }
5980
5981 if (mNetworkDetailCache == null) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005982 mNetworkDetailCache = new NetworkStats(SystemClock.elapsedRealtime(), 0);
5983 }
5984 }
5985 return mNetworkDetailCache;
5986 }
5987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005988}