blob: 86118b1d2904519b2b61d9a355c31d745496bc8c [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.net.NetworkStats.IFACE_ALL;
20import static android.net.NetworkStats.UID_ALL;
21import static android.text.format.DateUtils.SECOND_IN_MILLIS;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080022import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070023
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070024import android.bluetooth.BluetoothDevice;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070025import android.bluetooth.BluetoothHeadset;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070026import android.content.res.Resources;
27import android.net.ConnectivityManager;
28import android.net.NetworkStats;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070029import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.os.BatteryStats;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070031import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070032import android.os.Handler;
33import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.os.Parcel;
35import android.os.ParcelFormatException;
36import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070037import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.os.SystemClock;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080039import android.os.SystemProperties;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070040import android.os.WorkSource;
Amith Yamasanif37447b2009-10-08 18:28:01 -070041import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070042import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070043import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070045import android.util.LogWriter;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070046import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070048import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.util.SparseArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070050import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070052import com.android.internal.R;
53import com.android.internal.net.NetworkStatsFactory;
54import com.android.internal.util.JournaledFile;
55import com.google.android.collect.Sets;
56
Amith Yamasani3718aaa2009-06-09 06:32:35 -070057import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import java.io.File;
59import java.io.FileInputStream;
60import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070061import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070063import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import java.util.ArrayList;
65import java.util.HashMap;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070066import java.util.HashSet;
Evan Millarc64edde2009-04-18 12:26:32 -070067import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070068import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070070import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070071import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
73/**
74 * All information we are collecting about things that can happen that impact
75 * battery life. All times are represented in microseconds except where indicated
76 * otherwise.
77 */
78public final class BatteryStatsImpl extends BatteryStats {
79 private static final String TAG = "BatteryStatsImpl";
80 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070081 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -070082 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070083
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070084 // TODO: remove "tcp" from network methods, since we measure total stats.
85
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070087 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
89 // Current on-disk Parcel version
Dianne Hackborne8c88e62011-08-17 19:09:09 -070090 private static final int VERSION = 61 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -070091
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070092 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070093 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070094
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070095 // No, really, THIS is the maximum number of items we will record in the history.
96 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
97
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080098 // The maximum number of names wakelocks we will keep track of
99 // per uid; once the limit is reached, we batch the remaining wakelocks
100 // in to one common name.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700101 private static final int MAX_WAKELOCKS_PER_UID = 30;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700102
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700103 // The system process gets more. It is special. Oh so special.
104 // With, you know, special needs. Like this.
105 private static final int MAX_WAKELOCKS_PER_UID_IN_SYSTEM = 50;
106
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800107 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700108
Amith Yamasanie43530a2009-08-21 13:11:37 -0700109 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700111 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700113 static final int MSG_UPDATE_WAKELOCKS = 1;
114 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700115 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700116
117 public interface BatteryCallback {
118 public void batteryNeedsCpuUpdate();
119 public void batteryPowerChanged(boolean onBattery);
120 }
121
122 final class MyHandler extends Handler {
123 @Override
124 public void handleMessage(Message msg) {
125 BatteryCallback cb = mCallback;
126 switch (msg.what) {
127 case MSG_UPDATE_WAKELOCKS:
128 if (cb != null) {
129 cb.batteryNeedsCpuUpdate();
130 }
131 break;
132 case MSG_REPORT_POWER_CHANGE:
133 if (cb != null) {
134 cb.batteryPowerChanged(msg.arg1 != 0);
135 }
136 break;
137 }
138 }
139 }
140
141 private final MyHandler mHandler;
142
143 private BatteryCallback mCallback;
144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 /**
146 * The statistics we have collected organized by uids.
147 */
148 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
149 new SparseArray<BatteryStatsImpl.Uid>();
150
151 // A set of pools of currently active timers. When a timer is queried, we will divide the
152 // elapsed time by the number of active timers to arrive at that timer's share of the time.
153 // In order to do this, we must refresh each timer whenever the number of active timers
154 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700155 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
156 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
157 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
158 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
159 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700160 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
161 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
162 final ArrayList<StopwatchTimer> mScanWifiLockTimers = new ArrayList<StopwatchTimer>();
163 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700165 // Last partial timers we use for distributing CPU usage.
166 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 // These are the objects that will want to do something when the device
169 // is unplugged from power.
170 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700171
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700172 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700173
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700174 long mHistoryBaseTime;
175 boolean mHaveBatteryLevel = false;
176 boolean mRecordingHistory = true;
177 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700178
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700179 static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
180 static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700181 final Parcel mHistoryBuffer = Parcel.obtain();
182 final HistoryItem mHistoryLastWritten = new HistoryItem();
183 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700184 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700185 int mHistoryBufferLastPos = -1;
186 boolean mHistoryOverflow = false;
187 long mLastHistoryTime = 0;
188
189 final HistoryItem mHistoryCur = new HistoryItem();
190
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700191 HistoryItem mHistory;
192 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700193 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700194 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700195
196 private HistoryItem mHistoryIterator;
197 private boolean mReadOverflow;
198 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 int mStartCount;
201
202 long mBatteryUptime;
203 long mBatteryLastUptime;
204 long mBatteryRealtime;
205 long mBatteryLastRealtime;
206
207 long mUptime;
208 long mUptimeStart;
209 long mLastUptime;
210 long mRealtime;
211 long mRealtimeStart;
212 long mLastRealtime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700215 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700216
Dianne Hackborn617f8772009-03-31 15:04:46 -0700217 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700218 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700219
Dianne Hackborn617f8772009-03-31 15:04:46 -0700220 Counter mInputEventCounter;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700223 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700224
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700225 boolean mAudioOn;
226 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700227
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700228 boolean mVideoOn;
229 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700230
Dianne Hackborn627bba72009-03-24 22:32:56 -0700231 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800232 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700233 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800234 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700235
236 StopwatchTimer mPhoneSignalScanningTimer;
237
Dianne Hackborn627bba72009-03-24 22:32:56 -0700238 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700239 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700240 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700241
The Android Open Source Project10592532009-03-18 17:39:46 -0700242 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700243 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700244 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700245
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700246 boolean mGlobalWifiRunning;
247 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700248
The Android Open Source Project10592532009-03-18 17:39:46 -0700249 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700250 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700251
252 /** Bluetooth headset object */
253 BluetoothHeadset mBtHeadset;
254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 /**
256 * These provide time bases that discount the time the device is plugged
257 * in to power.
258 */
259 boolean mOnBattery;
260 boolean mOnBatteryInternal;
261 long mTrackBatteryPastUptime;
262 long mTrackBatteryUptimeStart;
263 long mTrackBatteryPastRealtime;
264 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 long mUnpluggedBatteryUptime;
267 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700268
The Android Open Source Project10592532009-03-18 17:39:46 -0700269 /*
270 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
271 */
Evan Millar633a1742009-04-02 16:36:33 -0700272 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700273 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700274 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700275 int mLowDischargeAmountSinceCharge;
276 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800277 int mDischargeScreenOnUnplugLevel;
278 int mDischargeScreenOffUnplugLevel;
279 int mDischargeAmountScreenOn;
280 int mDischargeAmountScreenOnSinceCharge;
281 int mDischargeAmountScreenOff;
282 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700285
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700286 // Mobile data transferred while on battery
287 private long[] mMobileDataTx = new long[4];
288 private long[] mMobileDataRx = new long[4];
289 private long[] mTotalDataTx = new long[4];
290 private long[] mTotalDataRx = new long[4];
291
292 private long mRadioDataUptime;
293 private long mRadioDataStart;
294
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700295 private int mBluetoothPingCount;
296 private int mBluetoothPingStart = -1;
297
Amith Yamasanif37447b2009-10-08 18:28:01 -0700298 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800299 private int mPhoneServiceStateRaw = -1;
300 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700301
Evan Millarc64edde2009-04-18 12:26:32 -0700302 /*
303 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
304 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700305 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700306 new HashMap<String, SamplingTimer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700307
Evan Millarc64edde2009-04-18 12:26:32 -0700308 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
309 return mKernelWakelockStats;
310 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700311
Evan Millarc64edde2009-04-18 12:26:32 -0700312 private static int sKernelWakelockUpdateVersion = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700313
Evan Millarc64edde2009-04-18 12:26:32 -0700314 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
315 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
316 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
317 Process.PROC_TAB_TERM,
318 Process.PROC_TAB_TERM,
319 Process.PROC_TAB_TERM,
320 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
321 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700322
Evan Millarc64edde2009-04-18 12:26:32 -0700323 private final String[] mProcWakelocksName = new String[3];
324 private final long[] mProcWakelocksData = new long[3];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700325
Evan Millarc64edde2009-04-18 12:26:32 -0700326 /*
327 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
328 * to mKernelWakelockStats.
329 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700330 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700331 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700333 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700334
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700335 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
336
337 /** Network ifaces that {@link ConnectivityManager} has claimed as mobile. */
338 private HashSet<String> mMobileIfaces = Sets.newHashSet();
339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 // For debugging
341 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700342 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700343 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 }
345
346 public static interface Unpluggable {
347 void unplug(long batteryUptime, long batteryRealtime);
348 void plug(long batteryUptime, long batteryRealtime);
349 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700352 * State for keeping track of counting information.
353 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700354 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700355 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700356 final ArrayList<Unpluggable> mUnpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700357 int mLoadedCount;
358 int mLastCount;
359 int mUnpluggedCount;
360 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700361
Dianne Hackborn617f8772009-03-31 15:04:46 -0700362 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700363 mUnpluggables = unpluggables;
Christopher Tate4cee7252010-03-19 14:50:40 -0700364 mPluggedCount = in.readInt();
365 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700366 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700367 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700368 mUnpluggedCount = in.readInt();
369 unpluggables.add(this);
370 }
371
372 Counter(ArrayList<Unpluggable> unpluggables) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700373 mUnpluggables = unpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700374 unpluggables.add(this);
375 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700376
Dianne Hackborn617f8772009-03-31 15:04:46 -0700377 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700378 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700379 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700380 out.writeInt(mUnpluggedCount);
381 }
382
383 public void unplug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700384 mUnpluggedCount = mPluggedCount;
385 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700386 }
387
388 public void plug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700389 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700390 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700391
Dianne Hackborn617f8772009-03-31 15:04:46 -0700392 /**
393 * Writes a possibly null Counter to a Parcel.
394 *
395 * @param out the Parcel to be written to.
396 * @param counter a Counter, or null.
397 */
398 public static void writeCounterToParcel(Parcel out, Counter counter) {
399 if (counter == null) {
400 out.writeInt(0); // indicates null
401 return;
402 }
403 out.writeInt(1); // indicates non-null
404
405 counter.writeToParcel(out);
406 }
407
408 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700409 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700410 int val;
411 if (which == STATS_LAST) {
412 val = mLastCount;
413 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700414 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700415 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700416 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700417 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700418 val -= mLoadedCount;
419 }
420 }
421
422 return val;
423 }
424
425 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700426 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700427 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
428 + " mUnpluggedCount=" + mUnpluggedCount
429 + " mPluggedCount=" + mPluggedCount);
430 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700431
Christopher Tate4cee7252010-03-19 14:50:40 -0700432 void stepAtomic() {
433 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700434 }
435
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700436 /**
437 * Clear state of this counter.
438 */
439 void reset(boolean detachIfReset) {
440 mCount.set(0);
441 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
442 if (detachIfReset) {
443 detach();
444 }
445 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700446
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700447 void detach() {
448 mUnpluggables.remove(this);
449 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700450
Dianne Hackborn617f8772009-03-31 15:04:46 -0700451 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700452 int count = mCount.get();
453 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700454 }
455
456 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700457 mLoadedCount = in.readInt();
458 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700459 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700460 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700461 }
462 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700463
464 public static class SamplingCounter extends Counter {
465
466 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
467 super(unpluggables, in);
468 }
469
470 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
471 super(unpluggables);
472 }
473
Christopher Tate4cee7252010-03-19 14:50:40 -0700474 public void addCountAtomic(long count) {
475 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700476 }
477 }
478
Dianne Hackborn617f8772009-03-31 15:04:46 -0700479 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 * State for keeping track of timing information.
481 */
Evan Millarc64edde2009-04-18 12:26:32 -0700482 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 final int mType;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700484 final ArrayList<Unpluggable> mUnpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 int mCount;
487 int mLoadedCount;
488 int mLastCount;
489 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 // Times are in microseconds for better accuracy when dividing by the
492 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 /**
495 * The total time we have accumulated since the start of the original
496 * boot, to the last time something interesting happened in the
497 * current run.
498 */
499 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 /**
502 * The total time we loaded for the previous runs. Subtract this from
503 * mTotalTime to find the time for the current run of the system.
504 */
505 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 /**
508 * The run time of the last run of the system, as loaded from the
509 * saved data.
510 */
511 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 /**
514 * The value of mTotalTime when unplug() was last called. Subtract
515 * this from mTotalTime to find the time since the last unplug from
516 * power.
517 */
518 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700519
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700520 /**
521 * Constructs from a parcel.
522 * @param type
523 * @param unpluggables
524 * @param powerType
525 * @param in
526 */
Evan Millarc64edde2009-04-18 12:26:32 -0700527 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700529 mUnpluggables = unpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 mCount = in.readInt();
532 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700533 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 mUnpluggedCount = in.readInt();
535 mTotalTime = in.readLong();
536 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700537 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 mUnpluggedTime = in.readLong();
539 unpluggables.add(this);
540 }
541
Evan Millarc64edde2009-04-18 12:26:32 -0700542 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700544 mUnpluggables = unpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 unpluggables.add(this);
546 }
Evan Millarc64edde2009-04-18 12:26:32 -0700547
548 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700549
Evan Millarc64edde2009-04-18 12:26:32 -0700550 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700551
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700552 /**
553 * Clear state of this timer. Returns true if the timer is inactive
554 * so can be completely dropped.
555 */
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700556 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700557 mTotalTime = mLoadedTime = mLastTime = 0;
558 mCount = mLoadedCount = mLastCount = 0;
559 if (detachIfReset) {
560 detach();
561 }
562 return true;
563 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700564
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700565 void detach() {
566 mUnpluggables.remove(this);
567 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 public void writeToParcel(Parcel out, long batteryRealtime) {
570 out.writeInt(mCount);
571 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 out.writeInt(mUnpluggedCount);
573 out.writeLong(computeRunTimeLocked(batteryRealtime));
574 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 out.writeLong(mUnpluggedTime);
576 }
577
578 public void unplug(long batteryUptime, long batteryRealtime) {
579 if (DEBUG && mType < 0) {
580 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
581 + " old mUnpluggedTime=" + mUnpluggedTime
582 + " old mUnpluggedCount=" + mUnpluggedCount);
583 }
584 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
585 mUnpluggedCount = mCount;
586 if (DEBUG && mType < 0) {
587 Log.v(TAG, "unplug #" + mType
588 + ": new mUnpluggedTime=" + mUnpluggedTime
589 + " new mUnpluggedCount=" + mUnpluggedCount);
590 }
591 }
592
593 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700594 if (DEBUG && mType < 0) {
595 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
596 + " old mTotalTime=" + mTotalTime);
597 }
598 mTotalTime = computeRunTimeLocked(batteryRealtime);
599 mCount = computeCurrentCountLocked();
600 if (DEBUG && mType < 0) {
601 Log.v(TAG, "plug #" + mType
602 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 }
604 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 /**
607 * Writes a possibly null Timer to a Parcel.
608 *
609 * @param out the Parcel to be written to.
610 * @param timer a Timer, or null.
611 */
612 public static void writeTimerToParcel(Parcel out, Timer timer,
613 long batteryRealtime) {
614 if (timer == null) {
615 out.writeInt(0); // indicates null
616 return;
617 }
618 out.writeInt(1); // indicates non-null
619
620 timer.writeToParcel(out, batteryRealtime);
621 }
622
623 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700624 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 long val;
626 if (which == STATS_LAST) {
627 val = mLastTime;
628 } else {
629 val = computeRunTimeLocked(batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700630 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 val -= mUnpluggedTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700632 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 val -= mLoadedTime;
634 }
635 }
636
637 return val;
638 }
639
640 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700641 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800642 int val;
643 if (which == STATS_LAST) {
644 val = mLastCount;
645 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700646 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700647 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700649 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 val -= mLoadedCount;
651 }
652 }
653
654 return val;
655 }
656
Dianne Hackborn627bba72009-03-24 22:32:56 -0700657 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700658 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
660 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700661 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800662 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700663 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700665 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700666
667
Evan Millarc64edde2009-04-18 12:26:32 -0700668 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
669 long runTime = computeRunTimeLocked(batteryRealtime);
670 // Divide by 1000 for backwards compatibility
671 out.writeLong((runTime + 500) / 1000);
Evan Millarc64edde2009-04-18 12:26:32 -0700672 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -0700673 }
674
675 void readSummaryFromParcelLocked(Parcel in) {
676 // Multiply by 1000 for backwards compatibility
677 mTotalTime = mLoadedTime = in.readLong() * 1000;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700678 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700679 mUnpluggedTime = mTotalTime;
680 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700681 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700682 mUnpluggedCount = mCount;
683 }
684 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700685
Evan Millarc64edde2009-04-18 12:26:32 -0700686 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700687
Evan Millarc64edde2009-04-18 12:26:32 -0700688 /**
689 * The most recent reported count from /proc/wakelocks.
690 */
691 int mCurrentReportedCount;
692
693 /**
694 * The reported count from /proc/wakelocks when unplug() was last
695 * called.
696 */
697 int mUnpluggedReportedCount;
698
699 /**
700 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700701 */
Evan Millarc64edde2009-04-18 12:26:32 -0700702 long mCurrentReportedTotalTime;
703
704
705 /**
706 * The reported total_time from /proc/wakelocks when unplug() was last
707 * called.
708 */
709 long mUnpluggedReportedTotalTime;
710
711 /**
712 * Whether we are currently in a discharge cycle.
713 */
714 boolean mInDischarge;
715
716 /**
717 * Whether we are currently recording reported values.
718 */
719 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700720
Evan Millarc64edde2009-04-18 12:26:32 -0700721 /*
722 * A sequnce counter, incremented once for each update of the stats.
723 */
724 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700725
Evan Millarc64edde2009-04-18 12:26:32 -0700726 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
727 super(0, unpluggables, in);
728 mCurrentReportedCount = in.readInt();
729 mUnpluggedReportedCount = in.readInt();
730 mCurrentReportedTotalTime = in.readLong();
731 mUnpluggedReportedTotalTime = in.readLong();
732 mTrackingReportedValues = in.readInt() == 1;
733 mInDischarge = inDischarge;
734 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700735
736 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
Evan Millarc64edde2009-04-18 12:26:32 -0700737 boolean trackReportedValues) {
738 super(0, unpluggables);
739 mTrackingReportedValues = trackReportedValues;
740 mInDischarge = inDischarge;
741 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700742
Evan Millarc64edde2009-04-18 12:26:32 -0700743 public void setStale() {
744 mTrackingReportedValues = false;
745 mUnpluggedReportedTotalTime = 0;
746 mUnpluggedReportedCount = 0;
747 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700748
Evan Millarc64edde2009-04-18 12:26:32 -0700749 public void setUpdateVersion(int version) {
750 mUpdateVersion = version;
751 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700752
Evan Millarc64edde2009-04-18 12:26:32 -0700753 public int getUpdateVersion() {
754 return mUpdateVersion;
755 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700756
Evan Millarc64edde2009-04-18 12:26:32 -0700757 public void updateCurrentReportedCount(int count) {
758 if (mInDischarge && mUnpluggedReportedCount == 0) {
759 // Updating the reported value for the first time.
760 mUnpluggedReportedCount = count;
761 // If we are receiving an update update mTrackingReportedValues;
762 mTrackingReportedValues = true;
763 }
764 mCurrentReportedCount = count;
765 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700766
Evan Millarc64edde2009-04-18 12:26:32 -0700767 public void updateCurrentReportedTotalTime(long totalTime) {
768 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
769 // Updating the reported value for the first time.
770 mUnpluggedReportedTotalTime = totalTime;
771 // If we are receiving an update update mTrackingReportedValues;
772 mTrackingReportedValues = true;
773 }
774 mCurrentReportedTotalTime = totalTime;
775 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700776
Evan Millarc64edde2009-04-18 12:26:32 -0700777 public void unplug(long batteryUptime, long batteryRealtime) {
778 super.unplug(batteryUptime, batteryRealtime);
779 if (mTrackingReportedValues) {
780 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
781 mUnpluggedReportedCount = mCurrentReportedCount;
782 }
783 mInDischarge = true;
784 }
785
786 public void plug(long batteryUptime, long batteryRealtime) {
787 super.plug(batteryUptime, batteryRealtime);
788 mInDischarge = false;
789 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700790
Evan Millarc64edde2009-04-18 12:26:32 -0700791 public void logState(Printer pw, String prefix) {
792 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700793 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -0700794 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
795 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
796 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
797 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700798
Evan Millarc64edde2009-04-18 12:26:32 -0700799 protected long computeRunTimeLocked(long curBatteryRealtime) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700800 return mTotalTime + (mInDischarge && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -0700801 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
802 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700803
Evan Millarc64edde2009-04-18 12:26:32 -0700804 protected int computeCurrentCountLocked() {
805 return mCount + (mInDischarge && mTrackingReportedValues
806 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
807 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700808
Evan Millarc64edde2009-04-18 12:26:32 -0700809 public void writeToParcel(Parcel out, long batteryRealtime) {
810 super.writeToParcel(out, batteryRealtime);
811 out.writeInt(mCurrentReportedCount);
812 out.writeInt(mUnpluggedReportedCount);
813 out.writeLong(mCurrentReportedTotalTime);
814 out.writeLong(mUnpluggedReportedTotalTime);
815 out.writeInt(mTrackingReportedValues ? 1 : 0);
816 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700817
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700818 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
819 super.reset(stats, detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700820 setStale();
821 return true;
822 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700823
Evan Millarc64edde2009-04-18 12:26:32 -0700824 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
825 super.writeSummaryFromParcelLocked(out, batteryRealtime);
826 out.writeLong(mCurrentReportedTotalTime);
827 out.writeInt(mCurrentReportedCount);
828 out.writeInt(mTrackingReportedValues ? 1 : 0);
829 }
830
831 void readSummaryFromParcelLocked(Parcel in) {
832 super.readSummaryFromParcelLocked(in);
833 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
834 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
835 mTrackingReportedValues = in.readInt() == 1;
836 }
837 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700838
Evan Millarc64edde2009-04-18 12:26:32 -0700839 /**
840 * State for keeping track of timing information.
841 */
842 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700843 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -0700844 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700845
Evan Millarc64edde2009-04-18 12:26:32 -0700846 int mNesting;
847
Evan Millarc64edde2009-04-18 12:26:32 -0700848 /**
849 * The last time at which we updated the timer. If mNesting is > 0,
850 * subtract this from the current battery time to find the amount of
851 * time we have been running since we last computed an update.
852 */
853 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700854
Evan Millarc64edde2009-04-18 12:26:32 -0700855 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700856 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -0700857 * was actually held for an interesting duration.
858 */
859 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700860
Amith Yamasanif37447b2009-10-08 18:28:01 -0700861 long mTimeout;
862
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700863 /**
864 * For partial wake locks, keep track of whether we are in the list
865 * to consume CPU cycles.
866 */
867 boolean mInList;
868
869 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700870 ArrayList<Unpluggable> unpluggables, Parcel in) {
871 super(type, unpluggables, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700872 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700873 mTimerPool = timerPool;
874 mUpdateTime = in.readLong();
875 }
876
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700877 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700878 ArrayList<Unpluggable> unpluggables) {
879 super(type, unpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700880 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700881 mTimerPool = timerPool;
882 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700883
Amith Yamasanif37447b2009-10-08 18:28:01 -0700884 void setTimeout(long timeout) {
885 mTimeout = timeout;
886 }
887
Evan Millarc64edde2009-04-18 12:26:32 -0700888 public void writeToParcel(Parcel out, long batteryRealtime) {
889 super.writeToParcel(out, batteryRealtime);
890 out.writeLong(mUpdateTime);
891 }
892
893 public void plug(long batteryUptime, long batteryRealtime) {
894 if (mNesting > 0) {
895 if (DEBUG && mType < 0) {
896 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
897 }
898 super.plug(batteryUptime, batteryRealtime);
899 mUpdateTime = batteryRealtime;
900 if (DEBUG && mType < 0) {
901 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
902 }
903 }
904 }
905
906 public void logState(Printer pw, String prefix) {
907 super.logState(pw, prefix);
908 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 + " mAcquireTime=" + mAcquireTime);
910 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 void startRunningLocked(BatteryStatsImpl stats) {
913 if (mNesting++ == 0) {
914 mUpdateTime = stats.getBatteryRealtimeLocked(
915 SystemClock.elapsedRealtime() * 1000);
916 if (mTimerPool != null) {
917 // Accumulate time to all currently active timers before adding
918 // this new one to the pool.
919 refreshTimersLocked(stats, mTimerPool);
920 // Add this timer to the active pool
921 mTimerPool.add(this);
922 }
923 // Increment the count
924 mCount++;
925 mAcquireTime = mTotalTime;
926 if (DEBUG && mType < 0) {
927 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
928 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
929 + " mAcquireTime=" + mAcquireTime);
930 }
931 }
932 }
933
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700934 boolean isRunningLocked() {
935 return mNesting > 0;
936 }
937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 void stopRunningLocked(BatteryStatsImpl stats) {
939 // Ignore attempt to stop a timer that isn't running
940 if (mNesting == 0) {
941 return;
942 }
943 if (--mNesting == 0) {
944 if (mTimerPool != null) {
945 // Accumulate time to all active counters, scaled by the total
946 // active in the pool, before taking this one out of the pool.
947 refreshTimersLocked(stats, mTimerPool);
948 // Remove this timer from the active pool
949 mTimerPool.remove(this);
950 } else {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700951 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
953 mNesting = 1;
954 mTotalTime = computeRunTimeLocked(batteryRealtime);
955 mNesting = 0;
956 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 if (DEBUG && mType < 0) {
959 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
960 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
961 + " mAcquireTime=" + mAcquireTime);
962 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 if (mTotalTime == mAcquireTime) {
965 // If there was no change in the time, then discard this
966 // count. A somewhat cheezy strategy, but hey.
967 mCount--;
968 }
969 }
970 }
971
972 // Update the total time for all other running Timers with the same type as this Timer
973 // due to a change in timer count
974 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700975 final ArrayList<StopwatchTimer> pool) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700976 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
978 final int N = pool.size();
979 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700980 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 long heldTime = batteryRealtime - t.mUpdateTime;
982 if (heldTime > 0) {
983 t.mTotalTime += heldTime / N;
984 }
985 t.mUpdateTime = batteryRealtime;
986 }
987 }
988
Evan Millarc64edde2009-04-18 12:26:32 -0700989 @Override
990 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700991 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
992 curBatteryRealtime = mUpdateTime + mTimeout;
993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 return mTotalTime + (mNesting > 0
995 ? (curBatteryRealtime - mUpdateTime)
996 / (mTimerPool != null ? mTimerPool.size() : 1)
997 : 0);
998 }
999
Evan Millarc64edde2009-04-18 12:26:32 -07001000 @Override
1001 protected int computeCurrentCountLocked() {
1002 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 }
1004
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001005 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001006 boolean canDetach = mNesting <= 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001007 super.reset(stats, canDetach && detachIfReset);
1008 if (mNesting > 0) {
1009 mUpdateTime = stats.getBatteryRealtimeLocked(
1010 SystemClock.elapsedRealtime() * 1000);
1011 }
1012 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001013 return canDetach;
1014 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001015
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001016 void detach() {
1017 super.detach();
1018 if (mTimerPool != null) {
1019 mTimerPool.remove(this);
1020 }
1021 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001024 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 mNesting = 0;
1026 }
1027 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001028
Evan Millarc64edde2009-04-18 12:26:32 -07001029 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001030
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001031 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -07001032 int len;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001033
Evan Millarc64edde2009-04-18 12:26:32 -07001034 try {
1035 FileInputStream is = new FileInputStream("/proc/wakelocks");
1036 len = is.read(buffer);
1037 is.close();
1038
1039 if (len > 0) {
1040 int i;
1041 for (i=0; i<len; i++) {
1042 if (buffer[i] == '\0') {
1043 len = i;
1044 break;
1045 }
1046 }
1047 }
1048 } catch (java.io.FileNotFoundException e) {
1049 return null;
1050 } catch (java.io.IOException e) {
1051 return null;
1052 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001053
Evan Millarc64edde2009-04-18 12:26:32 -07001054 return parseProcWakelocks(buffer, len);
1055 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001056
Evan Millarc64edde2009-04-18 12:26:32 -07001057 private final Map<String, KernelWakelockStats> parseProcWakelocks(
1058 byte[] wlBuffer, int len) {
1059 String name;
1060 int count;
1061 long totalTime;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001062 int startIndex;
1063 int endIndex;
Evan Millarc64edde2009-04-18 12:26:32 -07001064 int numUpdatedWlNames = 0;
1065
1066 // Advance past the first line.
1067 int i;
1068 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1069 startIndex = endIndex = i + 1;
1070
1071 synchronized(this) {
1072 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001073
Evan Millarc64edde2009-04-18 12:26:32 -07001074 sKernelWakelockUpdateVersion++;
1075 while (endIndex < len) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001076 for (endIndex=startIndex;
1077 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
Evan Millarc64edde2009-04-18 12:26:32 -07001078 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001079 endIndex++; // endIndex is an exclusive upper bound.
1080 // Don't go over the end of the buffer, Process.parseProcLine might
1081 // write to wlBuffer[endIndex]
1082 if (endIndex >= (len - 1) ) {
1083 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -07001084 }
Evan Millarc64edde2009-04-18 12:26:32 -07001085
1086 String[] nameStringArray = mProcWakelocksName;
1087 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001088 // Stomp out any bad characters since this is from a circular buffer
1089 // A corruption is seen sometimes that results in the vm crashing
1090 // This should prevent crashes and the line will probably fail to parse
1091 for (int j = startIndex; j < endIndex; j++) {
1092 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1093 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001094 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
1095 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001096
Evan Millarc64edde2009-04-18 12:26:32 -07001097 name = nameStringArray[0];
1098 count = (int) wlData[1];
1099 // convert nanoseconds to microseconds with rounding.
1100 totalTime = (wlData[2] + 500) / 1000;
1101
Amith Yamasani53b707b2009-09-30 11:05:30 -07001102 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001103 if (!m.containsKey(name)) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001104 m.put(name, new KernelWakelockStats(count, totalTime,
Evan Millarc64edde2009-04-18 12:26:32 -07001105 sKernelWakelockUpdateVersion));
1106 numUpdatedWlNames++;
1107 } else {
1108 KernelWakelockStats kwlStats = m.get(name);
1109 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1110 kwlStats.mCount += count;
1111 kwlStats.mTotalTime += totalTime;
1112 } else {
1113 kwlStats.mCount = count;
1114 kwlStats.mTotalTime = totalTime;
1115 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1116 numUpdatedWlNames++;
1117 }
1118 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001119 }
Evan Millarc64edde2009-04-18 12:26:32 -07001120 startIndex = endIndex;
1121 }
1122
1123 if (m.size() != numUpdatedWlNames) {
1124 // Don't report old data.
1125 Iterator<KernelWakelockStats> itr = m.values().iterator();
1126 while (itr.hasNext()) {
1127 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1128 itr.remove();
1129 }
1130 }
1131 }
1132 return m;
1133 }
1134 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001135
Evan Millarc64edde2009-04-18 12:26:32 -07001136 private class KernelWakelockStats {
1137 public int mCount;
1138 public long mTotalTime;
1139 public int mVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001140
Evan Millarc64edde2009-04-18 12:26:32 -07001141 KernelWakelockStats(int count, long totalTime, int version) {
1142 mCount = count;
1143 mTotalTime = totalTime;
1144 mVersion = version;
1145 }
1146 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001147
Evan Millarc64edde2009-04-18 12:26:32 -07001148 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001149 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001150 * doesn't already exist.
1151 */
1152 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1153 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1154 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001155 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07001156 true /* track reported values */);
1157 mKernelWakelockStats.put(name, kwlt);
1158 }
1159 return kwlt;
1160 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001161
1162 private void doDataPlug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001163 dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED];
1164 dataTransfer[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001165 }
1166
1167 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001168 dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001169 }
1170
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001171 /**
1172 * Radio uptime in microseconds when transferring data. This value is very approximate.
1173 * @return
1174 */
1175 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001176 try {
1177 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
1178 if (!awakeTimeFile.exists()) return 0;
1179 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
1180 String line = br.readLine();
1181 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001182 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001183 } catch (NumberFormatException nfe) {
1184 // Nothing
1185 } catch (IOException ioe) {
1186 // Nothing
1187 }
1188 return 0;
1189 }
1190
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001191 /**
1192 * @deprecated use getRadioDataUptime
1193 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001194 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001195 return getRadioDataUptime() / 1000;
1196 }
1197
1198 /**
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001199 * Returns the duration that the cell radio was up for data transfers.
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001200 */
1201 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001202 if (mRadioDataStart == -1) {
1203 return mRadioDataUptime;
1204 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001205 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001206 }
1207 }
1208
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001209 private int getCurrentBluetoothPingCount() {
1210 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001211 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1212 if (deviceList.size() > 0) {
1213 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001214 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001215 }
1216 return -1;
1217 }
1218
1219 public int getBluetoothPingCount() {
1220 if (mBluetoothPingStart == -1) {
1221 return mBluetoothPingCount;
1222 } else if (mBtHeadset != null) {
1223 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1224 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001225 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001226 }
1227
1228 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001229 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1230 mBluetoothPingStart = getCurrentBluetoothPingCount();
1231 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001232 mBtHeadset = headset;
1233 }
1234
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001235 int mChangedBufferStates = 0;
1236
1237 void addHistoryBufferLocked(long curTime) {
1238 if (!mHaveBatteryLevel || !mRecordingHistory) {
1239 return;
1240 }
1241
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001242 final long timeDiff = (mHistoryBaseTime+curTime) - mHistoryLastWritten.time;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001243 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001244 && timeDiff < 2000
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001245 && ((mHistoryLastWritten.states^mHistoryCur.states)&mChangedBufferStates) == 0) {
1246 // If the current is the same as the one before, then we no
1247 // longer need the entry.
1248 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
1249 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
1250 mHistoryBufferLastPos = -1;
1251 if (mHistoryLastLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001252 && timeDiff < 500 && mHistoryLastLastWritten.same(mHistoryCur)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001253 // If this results in us returning to the state written
1254 // prior to the last one, then we can just delete the last
1255 // written one and drop the new one. Nothing more to do.
1256 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
1257 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1258 return;
1259 }
1260 mChangedBufferStates |= mHistoryLastWritten.states^mHistoryCur.states;
1261 curTime = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001262 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001263 } else {
1264 mChangedBufferStates = 0;
1265 }
1266
1267 final int dataSize = mHistoryBuffer.dataSize();
1268 if (dataSize >= MAX_HISTORY_BUFFER) {
1269 if (!mHistoryOverflow) {
1270 mHistoryOverflow = true;
1271 addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW);
1272 }
1273
1274 // Once we've reached the maximum number of items, we only
1275 // record changes to the battery level and the most interesting states.
1276 // Once we've reached the maximum maximum number of items, we only
1277 // record changes to the battery level.
1278 if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
1279 (dataSize >= MAX_MAX_HISTORY_BUFFER
Amith Yamasani45f06462011-11-21 16:08:34 -08001280 || ((mHistoryLastWritten.states^mHistoryCur.states)
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001281 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
1282 return;
1283 }
1284 }
1285
1286 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE);
1287 }
1288
1289 void addHistoryBufferLocked(long curTime, byte cmd) {
1290 int origPos = 0;
1291 if (mIteratingHistory) {
1292 origPos = mHistoryBuffer.dataPosition();
1293 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
1294 }
1295 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
1296 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
1297 mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
1298 mHistoryLastWritten.writeDelta(mHistoryBuffer, mHistoryLastLastWritten);
1299 mLastHistoryTime = curTime;
1300 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
1301 + " now " + mHistoryBuffer.dataPosition()
1302 + " size is now " + mHistoryBuffer.dataSize());
1303 if (mIteratingHistory) {
1304 mHistoryBuffer.setDataPosition(origPos);
1305 }
1306 }
1307
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001308 int mChangedStates = 0;
1309
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001310 void addHistoryRecordLocked(long curTime) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001311 addHistoryBufferLocked(curTime);
1312
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001313 if (!USE_OLD_HISTORY) {
1314 return;
1315 }
1316
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001317 if (!mHaveBatteryLevel || !mRecordingHistory) {
1318 return;
1319 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001320
1321 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001322 // and no states have since the last recorded entry changed and
1323 // are now resetting back to their original value, then just collapse
1324 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001325 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001326 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000)
1327 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001328 // If the current is the same as the one before, then we no
1329 // longer need the entry.
1330 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001331 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500)
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001332 && mHistoryLastEnd.same(mHistoryCur)) {
1333 mHistoryLastEnd.next = null;
1334 mHistoryEnd.next = mHistoryCache;
1335 mHistoryCache = mHistoryEnd;
1336 mHistoryEnd = mHistoryLastEnd;
1337 mHistoryLastEnd = null;
1338 } else {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001339 mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001340 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
1341 }
1342 return;
1343 }
1344
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001345 mChangedStates = 0;
1346
1347 if (mNumHistoryItems == MAX_HISTORY_ITEMS
1348 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001349 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
1350 }
1351
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001352 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
1353 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001354 // record changes to the battery level and the most interesting states.
1355 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001356 // record changes to the battery level.
1357 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001358 == mHistoryCur.batteryLevel &&
1359 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
1360 || ((mHistoryEnd.states^mHistoryCur.states)
1361 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001362 return;
1363 }
1364 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001365
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001366 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
1367 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001368
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001369 void addHistoryRecordLocked(long curTime, byte cmd) {
1370 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001371 if (rec != null) {
1372 mHistoryCache = rec.next;
1373 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001374 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001375 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001376 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001377
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001378 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001379 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001380
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001381 void addHistoryRecordLocked(HistoryItem rec) {
1382 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001383 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001384 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001385 if (mHistoryEnd != null) {
1386 mHistoryEnd.next = rec;
1387 mHistoryEnd = rec;
1388 } else {
1389 mHistory = mHistoryEnd = rec;
1390 }
1391 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001392
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001393 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001394 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001395 if (USE_OLD_HISTORY) {
1396 if (mHistory != null) {
1397 mHistoryEnd.next = mHistoryCache;
1398 mHistoryCache = mHistory;
1399 mHistory = mHistoryLastEnd = mHistoryEnd = null;
1400 }
1401 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001402 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001403
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001404 mHistoryBaseTime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001405 mLastHistoryTime = 0;
1406
1407 mHistoryBuffer.setDataSize(0);
1408 mHistoryBuffer.setDataPosition(0);
1409 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER/2);
1410 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1411 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
1412 mHistoryBufferLastPos = -1;
1413 mHistoryOverflow = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001414 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001415
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001416 public void doUnplugLocked(long batteryUptime, long batteryRealtime) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001417 NetworkStats.Entry entry = null;
1418
1419 // Track UID data usage
1420 final NetworkStats uidStats = getNetworkStatsDetailGroupedByUid();
1421 final int size = uidStats.size();
1422 for (int i = 0; i < size; i++) {
1423 entry = uidStats.getValues(i, entry);
1424
1425 final Uid u = mUidStats.get(entry.uid);
1426 if (u == null) continue;
1427
1428 u.mStartedTcpBytesReceived = entry.rxBytes;
1429 u.mStartedTcpBytesSent = entry.txBytes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1431 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1432 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1435 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
1436 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001437
1438 // Track both mobile and total overall data
1439 final NetworkStats ifaceStats = getNetworkStatsSummary();
1440 entry = ifaceStats.getTotal(entry, mMobileIfaces);
1441 doDataUnplug(mMobileDataRx, entry.rxBytes);
1442 doDataUnplug(mMobileDataTx, entry.txBytes);
1443 entry = ifaceStats.getTotal(entry);
1444 doDataUnplug(mTotalDataRx, entry.rxBytes);
1445 doDataUnplug(mTotalDataTx, entry.txBytes);
1446
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001447 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001448 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001449 mRadioDataUptime = 0;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001450
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001451 // Track bt headset ping count
1452 mBluetoothPingStart = getCurrentBluetoothPingCount();
1453 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001455
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001456 public void doPlugLocked(long batteryUptime, long batteryRealtime) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001457 NetworkStats.Entry entry = null;
1458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1460 Uid u = mUidStats.valueAt(iu);
1461 if (u.mStartedTcpBytesReceived >= 0) {
1462 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1463 u.mStartedTcpBytesReceived = -1;
1464 }
1465 if (u.mStartedTcpBytesSent >= 0) {
1466 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1467 u.mStartedTcpBytesSent = -1;
1468 }
1469 }
1470 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1471 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
1472 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001473
1474 // Track both mobile and total overall data
1475 final NetworkStats ifaceStats = getNetworkStatsSummary();
1476 entry = ifaceStats.getTotal(entry, mMobileIfaces);
1477 doDataPlug(mMobileDataRx, entry.rxBytes);
1478 doDataPlug(mMobileDataTx, entry.txBytes);
1479 entry = ifaceStats.getTotal(entry);
1480 doDataPlug(mTotalDataRx, entry.rxBytes);
1481 doDataPlug(mTotalDataTx, entry.txBytes);
1482
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001483 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001484 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001485 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001486
1487 // Track bt headset ping count
1488 mBluetoothPingCount = getBluetoothPingCount();
1489 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001491
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001492 int mWakeLockNesting;
1493
1494 public void noteStartWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001495 if (type == WAKE_TYPE_PARTIAL) {
1496 // Only care about partial wake locks, since full wake locks
1497 // will be canceled when the user puts the screen to sleep.
1498 if (mWakeLockNesting == 0) {
1499 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
1500 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
1501 + Integer.toHexString(mHistoryCur.states));
1502 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1503 }
1504 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001505 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001506 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001507 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1508 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1509 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1510 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001511 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
1512 }
1513 }
1514
1515 public void noteStopWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001516 if (type == WAKE_TYPE_PARTIAL) {
1517 mWakeLockNesting--;
1518 if (mWakeLockNesting == 0) {
1519 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
1520 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
1521 + Integer.toHexString(mHistoryCur.states));
1522 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1523 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001524 }
1525 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001526 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1527 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1528 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1529 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001530 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
1531 }
1532 }
1533
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001534 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1535 int N = ws.size();
1536 for (int i=0; i<N; i++) {
1537 noteStartWakeLocked(ws.get(i), pid, name, type);
1538 }
1539 }
1540
1541 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1542 int N = ws.size();
1543 for (int i=0; i<N; i++) {
1544 noteStopWakeLocked(ws.get(i), pid, name, type);
1545 }
1546 }
1547
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001548 public int startAddingCpuLocked() {
1549 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
1550
1551 if (mScreenOn) {
1552 return 0;
1553 }
1554
1555 final int N = mPartialTimers.size();
1556 if (N == 0) {
1557 mLastPartialTimers.clear();
1558 return 0;
1559 }
1560
1561 // How many timers should consume CPU? Only want to include ones
1562 // that have already been in the list.
1563 for (int i=0; i<N; i++) {
1564 StopwatchTimer st = mPartialTimers.get(i);
1565 if (st.mInList) {
1566 Uid uid = st.mUid;
1567 // We don't include the system UID, because it so often
1568 // holds wake locks at one request or another of an app.
1569 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1570 return 50;
1571 }
1572 }
1573 }
1574
1575 return 0;
1576 }
1577
1578 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
1579 final int N = mPartialTimers.size();
1580 if (perc != 0) {
1581 int num = 0;
1582 for (int i=0; i<N; i++) {
1583 StopwatchTimer st = mPartialTimers.get(i);
1584 if (st.mInList) {
1585 Uid uid = st.mUid;
1586 // We don't include the system UID, because it so often
1587 // holds wake locks at one request or another of an app.
1588 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1589 num++;
1590 }
1591 }
1592 }
1593 if (num != 0) {
1594 for (int i=0; i<N; i++) {
1595 StopwatchTimer st = mPartialTimers.get(i);
1596 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001597 Uid uid = st.mUid;
1598 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07001599 int myUTime = utime/num;
1600 int mySTime = stime/num;
1601 utime -= myUTime;
1602 stime -= mySTime;
1603 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001604 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
1605 proc.addCpuTimeLocked(myUTime, mySTime);
1606 proc.addSpeedStepTimes(cpuSpeedTimes);
1607 }
1608 }
1609 }
1610 }
1611
1612 // Just in case, collect any lost CPU time.
1613 if (utime != 0 || stime != 0) {
1614 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
1615 if (uid != null) {
1616 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
1617 proc.addCpuTimeLocked(utime, stime);
1618 proc.addSpeedStepTimes(cpuSpeedTimes);
1619 }
1620 }
1621 }
1622
1623 final int NL = mLastPartialTimers.size();
1624 boolean diff = N != NL;
1625 for (int i=0; i<NL && !diff; i++) {
1626 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
1627 }
1628 if (!diff) {
1629 for (int i=0; i<NL; i++) {
1630 mPartialTimers.get(i).mInList = true;
1631 }
1632 return;
1633 }
1634
1635 for (int i=0; i<NL; i++) {
1636 mLastPartialTimers.get(i).mInList = false;
1637 }
1638 mLastPartialTimers.clear();
1639 for (int i=0; i<N; i++) {
1640 StopwatchTimer st = mPartialTimers.get(i);
1641 st.mInList = true;
1642 mLastPartialTimers.add(st);
1643 }
1644 }
1645
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001646 public void noteProcessDiedLocked(int uid, int pid) {
1647 Uid u = mUidStats.get(uid);
1648 if (u != null) {
1649 u.mPids.remove(pid);
1650 }
1651 }
1652
1653 public long getProcessWakeTime(int uid, int pid, long realtime) {
1654 Uid u = mUidStats.get(uid);
1655 if (u != null) {
1656 Uid.Pid p = u.mPids.get(pid);
1657 if (p != null) {
1658 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
1659 }
1660 }
1661 return 0;
1662 }
1663
1664 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
1665 Uid u = mUidStats.get(uid);
1666 if (u != null) {
1667 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
1668 }
1669 }
1670
Dianne Hackborn287952c2010-09-22 22:34:31 -07001671 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
1672 Uid u = mUidStats.get(uid);
1673 if (u != null) {
1674 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
1675 }
1676 }
1677
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001678 int mSensorNesting;
1679
1680 public void noteStartSensorLocked(int uid, int sensor) {
1681 if (mSensorNesting == 0) {
1682 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
1683 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
1684 + Integer.toHexString(mHistoryCur.states));
1685 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1686 }
1687 mSensorNesting++;
1688 getUidStatsLocked(uid).noteStartSensor(sensor);
1689 }
1690
1691 public void noteStopSensorLocked(int uid, int sensor) {
1692 mSensorNesting--;
1693 if (mSensorNesting == 0) {
1694 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
1695 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
1696 + Integer.toHexString(mHistoryCur.states));
1697 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1698 }
1699 getUidStatsLocked(uid).noteStopSensor(sensor);
1700 }
1701
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001702 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001703
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001704 public void noteStartGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001705 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001706 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001707 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
1708 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001709 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001710 }
1711 mGpsNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001712 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001713 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001714
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001715 public void noteStopGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001716 mGpsNesting--;
1717 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001718 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001719 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
1720 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001721 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001722 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001723 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001724 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001726 public void noteScreenOnLocked() {
1727 if (!mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001728 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001729 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
1730 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001731 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 mScreenOn = true;
1733 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001734 if (mScreenBrightnessBin >= 0) {
1735 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1736 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001737
1738 // Fake a wake lock, so we consider the device waked as long
1739 // as the screen is on.
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001740 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001741
1742 // Update discharge amounts.
1743 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001744 updateDischargeScreenLevelsLocked(false, true);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001745 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001746 }
1747 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001748
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 public void noteScreenOffLocked() {
1750 if (mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001751 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001752 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
1753 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001754 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 mScreenOn = false;
1756 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001757 if (mScreenBrightnessBin >= 0) {
1758 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1759 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001760
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001761 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001762
1763 // Update discharge amounts.
1764 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001765 updateDischargeScreenLevelsLocked(true, false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001766 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001767 }
1768 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001769
Dianne Hackborn617f8772009-03-31 15:04:46 -07001770 public void noteScreenBrightnessLocked(int brightness) {
1771 // Bin the brightness.
1772 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1773 if (bin < 0) bin = 0;
1774 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1775 if (mScreenBrightnessBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001776 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
1777 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001778 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
1779 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001780 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001781 if (mScreenOn) {
1782 if (mScreenBrightnessBin >= 0) {
1783 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1784 }
1785 mScreenBrightnessTimer[bin].startRunningLocked(this);
1786 }
1787 mScreenBrightnessBin = bin;
1788 }
1789 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001790
Christopher Tate4cee7252010-03-19 14:50:40 -07001791 public void noteInputEventAtomic() {
1792 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001793 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001794
Dianne Hackborn617f8772009-03-31 15:04:46 -07001795 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001796 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001797 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 public void notePhoneOnLocked() {
1800 if (!mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001801 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001802 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
1803 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001804 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001805 mPhoneOn = true;
1806 mPhoneOnTimer.startRunningLocked(this);
1807 }
1808 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001810 public void notePhoneOffLocked() {
1811 if (mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001812 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001813 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
1814 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001815 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 mPhoneOn = false;
1817 mPhoneOnTimer.stopRunningLocked(this);
1818 }
1819 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001820
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001821 void stopAllSignalStrengthTimersLocked(int except) {
Wink Saville52840902011-02-18 12:40:47 -08001822 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001823 if (i == except) {
1824 continue;
1825 }
1826 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1827 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
1828 }
1829 }
1830 }
1831
Dianne Hackborne4a59512010-12-07 11:08:07 -08001832 private int fixPhoneServiceState(int state, int signalBin) {
1833 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
1834 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1835 // to infer that we are scanning from other data.
1836 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08001837 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001838 state = ServiceState.STATE_IN_SERVICE;
1839 }
1840 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001841
Dianne Hackborne4a59512010-12-07 11:08:07 -08001842 return state;
1843 }
1844
1845 private void updateAllPhoneStateLocked(int state, int simState, int bin) {
1846 boolean scanning = false;
1847 boolean newHistory = false;
1848
1849 mPhoneServiceStateRaw = state;
1850 mPhoneSimStateRaw = simState;
1851 mPhoneSignalStrengthBinRaw = bin;
1852
1853 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
1854 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1855 // to infer that we are scanning from other data.
1856 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08001857 && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001858 state = ServiceState.STATE_IN_SERVICE;
1859 }
1860 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001861
1862 // If the phone is powered off, stop all timers.
1863 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001864 bin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001865
Dianne Hackborne4a59512010-12-07 11:08:07 -08001866 // If we are in service, make sure the correct signal string timer is running.
1867 } else if (state == ServiceState.STATE_IN_SERVICE) {
1868 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001869
1870 // If we're out of service, we are in the lowest signal strength
1871 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07001872 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001873 scanning = true;
Wink Saville52840902011-02-18 12:40:47 -08001874 bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001875 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001876 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001877 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001878 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
1879 + Integer.toHexString(mHistoryCur.states));
Amith Yamasanif37447b2009-10-08 18:28:01 -07001880 mPhoneSignalScanningTimer.startRunningLocked(this);
1881 }
1882 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001883
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001884 if (!scanning) {
1885 // If we are no longer scanning, then stop the scanning timer.
1886 if (mPhoneSignalScanningTimer.isRunningLocked()) {
1887 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
1888 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
1889 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001890 newHistory = true;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001891 mPhoneSignalScanningTimer.stopRunningLocked(this);
1892 }
1893 }
1894
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001895 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001896 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
1897 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08001898 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001899 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001900 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001901 mPhoneServiceState = state;
1902 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001903
1904 if (mPhoneSignalStrengthBin != bin) {
1905 if (mPhoneSignalStrengthBin >= 0) {
1906 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1907 }
1908 if (bin >= 0) {
1909 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1910 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1911 }
1912 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
1913 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
1914 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
1915 + Integer.toHexString(mHistoryCur.states));
1916 newHistory = true;
1917 } else {
1918 stopAllSignalStrengthTimersLocked(-1);
1919 }
1920 mPhoneSignalStrengthBin = bin;
1921 }
1922
1923 if (newHistory) {
1924 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1925 }
1926 }
1927
1928 /**
1929 * Telephony stack updates the phone state.
1930 * @param state phone state from ServiceState.getState()
1931 */
1932 public void notePhoneStateLocked(int state, int simState) {
1933 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001934 }
1935
Wink Savillee9b06d72009-05-18 21:47:50 -07001936 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001937 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08001938 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08001939 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001940 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001941
Dianne Hackborn627bba72009-03-24 22:32:56 -07001942 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1943 int bin = DATA_CONNECTION_NONE;
1944 if (hasData) {
1945 switch (dataType) {
1946 case TelephonyManager.NETWORK_TYPE_EDGE:
1947 bin = DATA_CONNECTION_EDGE;
1948 break;
1949 case TelephonyManager.NETWORK_TYPE_GPRS:
1950 bin = DATA_CONNECTION_GPRS;
1951 break;
1952 case TelephonyManager.NETWORK_TYPE_UMTS:
1953 bin = DATA_CONNECTION_UMTS;
1954 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001955 case TelephonyManager.NETWORK_TYPE_CDMA:
1956 bin = DATA_CONNECTION_CDMA;
1957 break;
1958 case TelephonyManager.NETWORK_TYPE_EVDO_0:
1959 bin = DATA_CONNECTION_EVDO_0;
1960 break;
1961 case TelephonyManager.NETWORK_TYPE_EVDO_A:
1962 bin = DATA_CONNECTION_EVDO_A;
1963 break;
1964 case TelephonyManager.NETWORK_TYPE_1xRTT:
1965 bin = DATA_CONNECTION_1xRTT;
1966 break;
1967 case TelephonyManager.NETWORK_TYPE_HSDPA:
1968 bin = DATA_CONNECTION_HSDPA;
1969 break;
1970 case TelephonyManager.NETWORK_TYPE_HSUPA:
1971 bin = DATA_CONNECTION_HSUPA;
1972 break;
1973 case TelephonyManager.NETWORK_TYPE_HSPA:
1974 bin = DATA_CONNECTION_HSPA;
1975 break;
1976 case TelephonyManager.NETWORK_TYPE_IDEN:
1977 bin = DATA_CONNECTION_IDEN;
1978 break;
1979 case TelephonyManager.NETWORK_TYPE_EVDO_B:
1980 bin = DATA_CONNECTION_EVDO_B;
1981 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07001982 case TelephonyManager.NETWORK_TYPE_LTE:
1983 bin = DATA_CONNECTION_LTE;
1984 break;
1985 case TelephonyManager.NETWORK_TYPE_EHRPD:
1986 bin = DATA_CONNECTION_EHRPD;
1987 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001988 default:
1989 bin = DATA_CONNECTION_OTHER;
1990 break;
1991 }
1992 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001993 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001994 if (mPhoneDataConnectionType != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001995 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
1996 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001997 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
1998 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001999 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07002000 if (mPhoneDataConnectionType >= 0) {
2001 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
2002 }
2003 mPhoneDataConnectionType = bin;
2004 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
2005 }
2006 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002007
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002008 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002009 if (!mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002010 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002011 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
2012 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002013 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002014 mWifiOn = true;
2015 mWifiOnTimer.startRunningLocked(this);
2016 }
2017 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002018
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002019 public void noteWifiOffLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002020 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002021 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002022 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
2023 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002024 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002025 mWifiOn = false;
2026 mWifiOnTimer.stopRunningLocked(this);
2027 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002028 if (mWifiOnUid >= 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002029 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002030 mWifiOnUid = -1;
2031 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002032 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002033
2034 public void noteAudioOnLocked(int uid) {
2035 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002036 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002037 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
2038 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002039 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002040 mAudioOn = true;
2041 mAudioOnTimer.startRunningLocked(this);
2042 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002043 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002044 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002045
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002046 public void noteAudioOffLocked(int uid) {
2047 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002048 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002049 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
2050 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002051 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002052 mAudioOn = false;
2053 mAudioOnTimer.stopRunningLocked(this);
2054 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002055 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002056 }
2057
2058 public void noteVideoOnLocked(int uid) {
2059 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002060 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002061 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
2062 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002063 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002064 mVideoOn = true;
2065 mVideoOnTimer.startRunningLocked(this);
2066 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002067 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002068 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002069
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002070 public void noteVideoOffLocked(int uid) {
2071 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002072 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002073 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
2074 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002075 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002076 mVideoOn = false;
2077 mVideoOnTimer.stopRunningLocked(this);
2078 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002079 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002080 }
2081
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002082 public void noteWifiRunningLocked(WorkSource ws) {
2083 if (!mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002084 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002085 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
2086 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002087 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002088 mGlobalWifiRunning = true;
2089 mGlobalWifiRunningTimer.startRunningLocked(this);
2090 int N = ws.size();
2091 for (int i=0; i<N; i++) {
2092 getUidStatsLocked(ws.get(i)).noteWifiRunningLocked();
2093 }
2094 } else {
2095 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002096 }
2097 }
2098
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002099 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
2100 if (mGlobalWifiRunning) {
2101 int N = oldWs.size();
2102 for (int i=0; i<N; i++) {
2103 getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked();
2104 }
2105 N = newWs.size();
2106 for (int i=0; i<N; i++) {
2107 getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked();
2108 }
2109 } else {
2110 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
2111 }
2112 }
2113
2114 public void noteWifiStoppedLocked(WorkSource ws) {
2115 if (mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002116 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002117 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
2118 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002119 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002120 mGlobalWifiRunning = false;
2121 mGlobalWifiRunningTimer.stopRunningLocked(this);
2122 int N = ws.size();
2123 for (int i=0; i<N; i++) {
2124 getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked();
2125 }
2126 } else {
2127 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002128 }
2129 }
2130
The Android Open Source Project10592532009-03-18 17:39:46 -07002131 public void noteBluetoothOnLocked() {
2132 if (!mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002133 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002134 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
2135 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002136 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002137 mBluetoothOn = true;
2138 mBluetoothOnTimer.startRunningLocked(this);
2139 }
2140 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002141
The Android Open Source Project10592532009-03-18 17:39:46 -07002142 public void noteBluetoothOffLocked() {
2143 if (mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002144 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002145 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
2146 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002147 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002148 mBluetoothOn = false;
2149 mBluetoothOnTimer.stopRunningLocked(this);
2150 }
2151 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002152
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002153 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002154
The Android Open Source Project10592532009-03-18 17:39:46 -07002155 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002156 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002157 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002158 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
2159 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002160 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002161 }
2162 mWifiFullLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002163 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002164 }
2165
2166 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002167 mWifiFullLockNesting--;
2168 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002169 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002170 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
2171 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002172 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002173 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002174 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002175 }
2176
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002177 int mWifiScanLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002178
The Android Open Source Project10592532009-03-18 17:39:46 -07002179 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002180 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002181 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002182 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: "
2183 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002184 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002185 }
2186 mWifiScanLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002187 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002188 }
2189
2190 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002191 mWifiScanLockNesting--;
2192 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002193 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002194 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: "
2195 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002196 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002197 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002198 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002199 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002200
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002201 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002202
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002203 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002204 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002205 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002206 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
2207 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002208 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002209 }
2210 mWifiMulticastNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002211 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002212 }
2213
2214 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002215 mWifiMulticastNesting--;
2216 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002217 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002218 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
2219 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002220 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002221 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002222 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002223 }
2224
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002225 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2226 int N = ws.size();
2227 for (int i=0; i<N; i++) {
2228 noteFullWifiLockAcquiredLocked(ws.get(i));
2229 }
2230 }
2231
2232 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
2233 int N = ws.size();
2234 for (int i=0; i<N; i++) {
2235 noteFullWifiLockReleasedLocked(ws.get(i));
2236 }
2237 }
2238
2239 public void noteScanWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2240 int N = ws.size();
2241 for (int i=0; i<N; i++) {
2242 noteScanWifiLockAcquiredLocked(ws.get(i));
2243 }
2244 }
2245
2246 public void noteScanWifiLockReleasedFromSourceLocked(WorkSource ws) {
2247 int N = ws.size();
2248 for (int i=0; i<N; i++) {
2249 noteScanWifiLockReleasedLocked(ws.get(i));
2250 }
2251 }
2252
2253 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
2254 int N = ws.size();
2255 for (int i=0; i<N; i++) {
2256 noteWifiMulticastEnabledLocked(ws.get(i));
2257 }
2258 }
2259
2260 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
2261 int N = ws.size();
2262 for (int i=0; i<N; i++) {
2263 noteWifiMulticastDisabledLocked(ws.get(i));
2264 }
2265 }
2266
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002267 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
2268 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
2269 mMobileIfaces.add(iface);
2270 } else {
2271 mMobileIfaces.remove(iface);
2272 }
2273 }
2274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002276 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002277 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002278
Dianne Hackborn617f8772009-03-31 15:04:46 -07002279 @Override public long getScreenBrightnessTime(int brightnessBin,
2280 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002281 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07002282 batteryRealtime, which);
2283 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002284
Dianne Hackborn617f8772009-03-31 15:04:46 -07002285 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002286 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002287 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002290 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002292
Dianne Hackborn627bba72009-03-24 22:32:56 -07002293 @Override public long getPhoneSignalStrengthTime(int strengthBin,
2294 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002295 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002296 batteryRealtime, which);
2297 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002298
2299 @Override public long getPhoneSignalScanningTime(
2300 long batteryRealtime, int which) {
2301 return mPhoneSignalScanningTimer.getTotalTimeLocked(
2302 batteryRealtime, which);
2303 }
2304
Dianne Hackborn617f8772009-03-31 15:04:46 -07002305 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002306 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002307 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002308
Dianne Hackborn627bba72009-03-24 22:32:56 -07002309 @Override public long getPhoneDataConnectionTime(int dataType,
2310 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002311 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002312 batteryRealtime, which);
2313 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002314
Dianne Hackborn617f8772009-03-31 15:04:46 -07002315 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002316 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002317 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002318
The Android Open Source Project10592532009-03-18 17:39:46 -07002319 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002320 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002321 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002322
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002323 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) {
2324 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002325 }
2326
The Android Open Source Project10592532009-03-18 17:39:46 -07002327 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002328 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002329 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002331 @Override public boolean getIsOnBattery() {
2332 return mOnBattery;
2333 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002335 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
2336 return mUidStats;
2337 }
2338
2339 /**
2340 * The statistics associated with a particular uid.
2341 */
2342 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002344 final int mUid;
2345 long mLoadedTcpBytesReceived;
2346 long mLoadedTcpBytesSent;
2347 long mCurrentTcpBytesReceived;
2348 long mCurrentTcpBytesSent;
2349 long mTcpBytesReceivedAtLastUnplug;
2350 long mTcpBytesSentAtLastUnplug;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 // These are not saved/restored when parcelling, since we want
2353 // to return from the parcel with a snapshot of the state.
2354 long mStartedTcpBytesReceived = -1;
2355 long mStartedTcpBytesSent = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002356
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002357 boolean mWifiRunning;
2358 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002359
The Android Open Source Project10592532009-03-18 17:39:46 -07002360 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002361 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002362
The Android Open Source Project10592532009-03-18 17:39:46 -07002363 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002364 StopwatchTimer mScanWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002365
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002366 boolean mWifiMulticastEnabled;
2367 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002368
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002369 boolean mAudioTurnedOn;
2370 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002371
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002372 boolean mVideoTurnedOn;
2373 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002374
Dianne Hackborn617f8772009-03-31 15:04:46 -07002375 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 /**
2378 * The statistics we have collected for this uid's wake locks.
2379 */
2380 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
2381
2382 /**
2383 * The statistics we have collected for this uid's sensor activations.
2384 */
2385 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
2386
2387 /**
2388 * The statistics we have collected for this uid's processes.
2389 */
2390 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
2391
2392 /**
2393 * The statistics we have collected for this uid's processes.
2394 */
2395 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002396
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002397 /**
2398 * The transient wake stats we have collected for this uid's pids.
2399 */
2400 final SparseArray<Pid> mPids = new SparseArray<Pid>();
2401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 public Uid(int uid) {
2403 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002404 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2405 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002406 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002407 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002408 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002409 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002410 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002411 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002412 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
2413 null, mUnpluggables);
2414 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
2415 null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002416 }
2417
2418 @Override
2419 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
2420 return mWakelockStats;
2421 }
2422
2423 @Override
2424 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
2425 return mSensorStats;
2426 }
2427
2428 @Override
2429 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
2430 return mProcessStats;
2431 }
2432
2433 @Override
2434 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
2435 return mPackageStats;
2436 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002437
2438 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 public int getUid() {
2440 return mUid;
2441 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002442
2443 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 public long getTcpBytesReceived(int which) {
2445 if (which == STATS_LAST) {
2446 return mLoadedTcpBytesReceived;
2447 } else {
2448 long current = computeCurrentTcpBytesReceived();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002449 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 current -= mTcpBytesReceivedAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002451 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 current += mLoadedTcpBytesReceived;
2453 }
2454 return current;
2455 }
2456 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002458 public long computeCurrentTcpBytesReceived() {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002459 final long uidRxBytes = getNetworkStatsDetailGroupedByUid().getTotal(
2460 null, mUid).rxBytes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002462 ? (uidRxBytes - mStartedTcpBytesReceived) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002463 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002464
2465 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002466 public long getTcpBytesSent(int which) {
2467 if (which == STATS_LAST) {
2468 return mLoadedTcpBytesSent;
2469 } else {
2470 long current = computeCurrentTcpBytesSent();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002471 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 current -= mTcpBytesSentAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002473 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002474 current += mLoadedTcpBytesSent;
2475 }
2476 return current;
2477 }
2478 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002479
The Android Open Source Project10592532009-03-18 17:39:46 -07002480 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002481 public void noteWifiRunningLocked() {
2482 if (!mWifiRunning) {
2483 mWifiRunning = true;
2484 if (mWifiRunningTimer == null) {
2485 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2486 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002487 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002488 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002489 }
2490 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002491
Dianne Hackborn617f8772009-03-31 15:04:46 -07002492 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002493 public void noteWifiStoppedLocked() {
2494 if (mWifiRunning) {
2495 mWifiRunning = false;
2496 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002497 }
2498 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002499
Dianne Hackborn617f8772009-03-31 15:04:46 -07002500 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002501 public void noteFullWifiLockAcquiredLocked() {
2502 if (!mFullWifiLockOut) {
2503 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002504 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002505 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002506 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002507 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002508 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2509 }
2510 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002511
The Android Open Source Project10592532009-03-18 17:39:46 -07002512 @Override
2513 public void noteFullWifiLockReleasedLocked() {
2514 if (mFullWifiLockOut) {
2515 mFullWifiLockOut = false;
2516 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2517 }
2518 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002519
The Android Open Source Project10592532009-03-18 17:39:46 -07002520 @Override
2521 public void noteScanWifiLockAcquiredLocked() {
2522 if (!mScanWifiLockOut) {
2523 mScanWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002524 if (mScanWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002525 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002526 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002527 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002528 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2529 }
2530 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002531
The Android Open Source Project10592532009-03-18 17:39:46 -07002532 @Override
2533 public void noteScanWifiLockReleasedLocked() {
2534 if (mScanWifiLockOut) {
2535 mScanWifiLockOut = false;
2536 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2537 }
2538 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002539
2540 @Override
2541 public void noteWifiMulticastEnabledLocked() {
2542 if (!mWifiMulticastEnabled) {
2543 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002544 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002545 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002546 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002547 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002548 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
2549 }
2550 }
2551
2552 @Override
2553 public void noteWifiMulticastDisabledLocked() {
2554 if (mWifiMulticastEnabled) {
2555 mWifiMulticastEnabled = false;
2556 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
2557 }
2558 }
2559
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002560 @Override
2561 public void noteAudioTurnedOnLocked() {
2562 if (!mAudioTurnedOn) {
2563 mAudioTurnedOn = true;
2564 if (mAudioTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002565 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002566 null, mUnpluggables);
2567 }
2568 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2569 }
2570 }
2571
2572 @Override
2573 public void noteAudioTurnedOffLocked() {
2574 if (mAudioTurnedOn) {
2575 mAudioTurnedOn = false;
2576 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2577 }
2578 }
2579
2580 @Override
2581 public void noteVideoTurnedOnLocked() {
2582 if (!mVideoTurnedOn) {
2583 mVideoTurnedOn = true;
2584 if (mVideoTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002585 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002586 null, mUnpluggables);
2587 }
2588 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2589 }
2590 }
2591
2592 @Override
2593 public void noteVideoTurnedOffLocked() {
2594 if (mVideoTurnedOn) {
2595 mVideoTurnedOn = false;
2596 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2597 }
2598 }
2599
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002600 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002601 public long getWifiRunningTime(long batteryRealtime, int which) {
2602 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002603 return 0;
2604 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002605 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002606 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002607
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002608 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002609 public long getFullWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002610 if (mFullWifiLockTimer == null) {
2611 return 0;
2612 }
Evan Millarc64edde2009-04-18 12:26:32 -07002613 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002614 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002615
2616 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002617 public long getScanWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002618 if (mScanWifiLockTimer == null) {
2619 return 0;
2620 }
Evan Millarc64edde2009-04-18 12:26:32 -07002621 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002622 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002623
2624 @Override
2625 public long getWifiMulticastTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002626 if (mWifiMulticastTimer == null) {
2627 return 0;
2628 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002629 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
2630 which);
2631 }
2632
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002633 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002634 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
2635 if (mAudioTurnedOnTimer == null) {
2636 return 0;
2637 }
2638 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2639 }
2640
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002641 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002642 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
2643 if (mVideoTurnedOnTimer == null) {
2644 return 0;
2645 }
2646 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2647 }
2648
Dianne Hackborn617f8772009-03-31 15:04:46 -07002649 @Override
2650 public void noteUserActivityLocked(int type) {
2651 if (mUserActivityCounters == null) {
2652 initUserActivityLocked();
2653 }
2654 if (type < 0) type = 0;
2655 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
Christopher Tate4cee7252010-03-19 14:50:40 -07002656 mUserActivityCounters[type].stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002657 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002658
Dianne Hackborn617f8772009-03-31 15:04:46 -07002659 @Override
2660 public boolean hasUserActivity() {
2661 return mUserActivityCounters != null;
2662 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002663
Dianne Hackborn617f8772009-03-31 15:04:46 -07002664 @Override
2665 public int getUserActivityCount(int type, int which) {
2666 if (mUserActivityCounters == null) {
2667 return 0;
2668 }
Evan Millarc64edde2009-04-18 12:26:32 -07002669 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002670 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002671
Dianne Hackborn617f8772009-03-31 15:04:46 -07002672 void initUserActivityLocked() {
2673 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2674 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2675 mUserActivityCounters[i] = new Counter(mUnpluggables);
2676 }
2677 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679 public long computeCurrentTcpBytesSent() {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002680 final long uidTxBytes = getNetworkStatsDetailGroupedByUid().getTotal(
2681 null, mUid).txBytes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002683 ? (uidTxBytes - mStartedTcpBytesSent) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002684 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002685
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002686 /**
2687 * Clear all stats for this uid. Returns true if the uid is completely
2688 * inactive so can be dropped.
2689 */
2690 boolean reset() {
2691 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002692
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002693 if (mWifiRunningTimer != null) {
2694 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false);
2695 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002696 }
2697 if (mFullWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002698 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002699 active |= mFullWifiLockOut;
2700 }
2701 if (mScanWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002702 active |= !mScanWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002703 active |= mScanWifiLockOut;
2704 }
2705 if (mWifiMulticastTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002706 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002707 active |= mWifiMulticastEnabled;
2708 }
2709 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002710 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002711 active |= mAudioTurnedOn;
2712 }
2713 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002714 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002715 active |= mVideoTurnedOn;
2716 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002717
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002718 mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0;
2719 mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002720
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002721 if (mUserActivityCounters != null) {
2722 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2723 mUserActivityCounters[i].reset(false);
2724 }
2725 }
2726
2727 if (mWakelockStats.size() > 0) {
2728 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
2729 while (it.hasNext()) {
2730 Map.Entry<String, Wakelock> wakelockEntry = it.next();
2731 Wakelock wl = wakelockEntry.getValue();
2732 if (wl.reset()) {
2733 it.remove();
2734 } else {
2735 active = true;
2736 }
2737 }
2738 }
2739 if (mSensorStats.size() > 0) {
2740 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
2741 while (it.hasNext()) {
2742 Map.Entry<Integer, Sensor> sensorEntry = it.next();
2743 Sensor s = sensorEntry.getValue();
2744 if (s.reset()) {
2745 it.remove();
2746 } else {
2747 active = true;
2748 }
2749 }
2750 }
2751 if (mProcessStats.size() > 0) {
2752 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
2753 while (it.hasNext()) {
2754 Map.Entry<String, Proc> procEntry = it.next();
2755 procEntry.getValue().detach();
2756 }
2757 mProcessStats.clear();
2758 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002759 if (mPids.size() > 0) {
2760 for (int i=0; !active && i<mPids.size(); i++) {
2761 Pid pid = mPids.valueAt(i);
2762 if (pid.mWakeStart != 0) {
2763 active = true;
2764 }
2765 }
2766 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002767 if (mPackageStats.size() > 0) {
2768 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
2769 while (it.hasNext()) {
2770 Map.Entry<String, Pkg> pkgEntry = it.next();
2771 Pkg p = pkgEntry.getValue();
2772 p.detach();
2773 if (p.mServiceStats.size() > 0) {
2774 Iterator<Map.Entry<String, Pkg.Serv>> it2
2775 = p.mServiceStats.entrySet().iterator();
2776 while (it2.hasNext()) {
2777 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
2778 servEntry.getValue().detach();
2779 }
2780 }
2781 }
2782 mPackageStats.clear();
2783 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002784
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002785 mPids.clear();
2786
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002787 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002788 if (mWifiRunningTimer != null) {
2789 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002790 }
2791 if (mFullWifiLockTimer != null) {
2792 mFullWifiLockTimer.detach();
2793 }
2794 if (mScanWifiLockTimer != null) {
2795 mScanWifiLockTimer.detach();
2796 }
2797 if (mWifiMulticastTimer != null) {
2798 mWifiMulticastTimer.detach();
2799 }
2800 if (mAudioTurnedOnTimer != null) {
2801 mAudioTurnedOnTimer.detach();
2802 }
2803 if (mVideoTurnedOnTimer != null) {
2804 mVideoTurnedOnTimer.detach();
2805 }
2806 if (mUserActivityCounters != null) {
2807 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2808 mUserActivityCounters[i].detach();
2809 }
2810 }
2811 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002812
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002813 return !active;
2814 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2817 out.writeInt(mWakelockStats.size());
2818 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
2819 out.writeString(wakelockEntry.getKey());
2820 Uid.Wakelock wakelock = wakelockEntry.getValue();
2821 wakelock.writeToParcelLocked(out, batteryRealtime);
2822 }
2823
2824 out.writeInt(mSensorStats.size());
2825 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
2826 out.writeInt(sensorEntry.getKey());
2827 Uid.Sensor sensor = sensorEntry.getValue();
2828 sensor.writeToParcelLocked(out, batteryRealtime);
2829 }
2830
2831 out.writeInt(mProcessStats.size());
2832 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
2833 out.writeString(procEntry.getKey());
2834 Uid.Proc proc = procEntry.getValue();
2835 proc.writeToParcelLocked(out);
2836 }
2837
2838 out.writeInt(mPackageStats.size());
2839 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
2840 out.writeString(pkgEntry.getKey());
2841 Uid.Pkg pkg = pkgEntry.getValue();
2842 pkg.writeToParcelLocked(out);
2843 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002845 out.writeLong(mLoadedTcpBytesReceived);
2846 out.writeLong(mLoadedTcpBytesSent);
2847 out.writeLong(computeCurrentTcpBytesReceived());
2848 out.writeLong(computeCurrentTcpBytesSent());
2849 out.writeLong(mTcpBytesReceivedAtLastUnplug);
2850 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002851 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002852 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002853 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002854 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002855 out.writeInt(0);
2856 }
2857 if (mFullWifiLockTimer != null) {
2858 out.writeInt(1);
2859 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
2860 } else {
2861 out.writeInt(0);
2862 }
2863 if (mScanWifiLockTimer != null) {
2864 out.writeInt(1);
2865 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
2866 } else {
2867 out.writeInt(0);
2868 }
2869 if (mWifiMulticastTimer != null) {
2870 out.writeInt(1);
2871 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
2872 } else {
2873 out.writeInt(0);
2874 }
2875 if (mAudioTurnedOnTimer != null) {
2876 out.writeInt(1);
2877 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
2878 } else {
2879 out.writeInt(0);
2880 }
2881 if (mVideoTurnedOnTimer != null) {
2882 out.writeInt(1);
2883 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
2884 } else {
2885 out.writeInt(0);
2886 }
2887 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002888 out.writeInt(1);
2889 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2890 mUserActivityCounters[i].writeToParcel(out);
2891 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002892 } else {
2893 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002895 }
2896
2897 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2898 int numWakelocks = in.readInt();
2899 mWakelockStats.clear();
2900 for (int j = 0; j < numWakelocks; j++) {
2901 String wakelockName = in.readString();
2902 Uid.Wakelock wakelock = new Wakelock();
2903 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackbornc24ab862011-10-18 15:55:03 -07002904 // We will just drop some random set of wakelocks if
2905 // the previous run of the system was an older version
2906 // that didn't impose a limit.
2907 mWakelockStats.put(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002908 }
2909
2910 int numSensors = in.readInt();
2911 mSensorStats.clear();
2912 for (int k = 0; k < numSensors; k++) {
2913 int sensorNumber = in.readInt();
2914 Uid.Sensor sensor = new Sensor(sensorNumber);
2915 sensor.readFromParcelLocked(mUnpluggables, in);
2916 mSensorStats.put(sensorNumber, sensor);
2917 }
2918
2919 int numProcs = in.readInt();
2920 mProcessStats.clear();
2921 for (int k = 0; k < numProcs; k++) {
2922 String processName = in.readString();
2923 Uid.Proc proc = new Proc();
2924 proc.readFromParcelLocked(in);
2925 mProcessStats.put(processName, proc);
2926 }
2927
2928 int numPkgs = in.readInt();
2929 mPackageStats.clear();
2930 for (int l = 0; l < numPkgs; l++) {
2931 String packageName = in.readString();
2932 Uid.Pkg pkg = new Pkg();
2933 pkg.readFromParcelLocked(in);
2934 mPackageStats.put(packageName, pkg);
2935 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002937 mLoadedTcpBytesReceived = in.readLong();
2938 mLoadedTcpBytesSent = in.readLong();
2939 mCurrentTcpBytesReceived = in.readLong();
2940 mCurrentTcpBytesSent = in.readLong();
2941 mTcpBytesReceivedAtLastUnplug = in.readLong();
2942 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002943 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002944 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002945 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2946 mWifiRunningTimers, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002947 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002948 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002949 }
2950 mFullWifiLockOut = false;
2951 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002952 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002953 mFullWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002954 } else {
2955 mFullWifiLockTimer = null;
2956 }
2957 mScanWifiLockOut = false;
2958 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002959 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002960 mScanWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002961 } else {
2962 mScanWifiLockTimer = null;
2963 }
2964 mWifiMulticastEnabled = false;
2965 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002966 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002967 mWifiMulticastTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002968 } else {
2969 mWifiMulticastTimer = null;
2970 }
2971 mAudioTurnedOn = false;
2972 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002973 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002974 null, mUnpluggables, in);
2975 } else {
2976 mAudioTurnedOnTimer = null;
2977 }
2978 mVideoTurnedOn = false;
2979 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002980 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002981 null, mUnpluggables, in);
2982 } else {
2983 mVideoTurnedOnTimer = null;
2984 }
2985 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002986 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2987 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2988 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
2989 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002990 } else {
2991 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07002992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002993 }
2994
2995 /**
2996 * The statistics associated with a particular wake lock.
2997 */
2998 public final class Wakelock extends BatteryStats.Uid.Wakelock {
2999 /**
3000 * How long (in ms) this uid has been keeping the device partially awake.
3001 */
Evan Millarc64edde2009-04-18 12:26:32 -07003002 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003003
3004 /**
3005 * How long (in ms) this uid has been keeping the device fully awake.
3006 */
Evan Millarc64edde2009-04-18 12:26:32 -07003007 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003008
3009 /**
3010 * How long (in ms) this uid has had a window keeping the device awake.
3011 */
Evan Millarc64edde2009-04-18 12:26:32 -07003012 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003013
3014 /**
3015 * Reads a possibly null Timer from a Parcel. The timer is associated with the
3016 * proper timer pool from the given BatteryStatsImpl object.
3017 *
3018 * @param in the Parcel to be read from.
3019 * return a new Timer, or null.
3020 */
Evan Millarc64edde2009-04-18 12:26:32 -07003021 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 ArrayList<Unpluggable> unpluggables, Parcel in) {
3023 if (in.readInt() == 0) {
3024 return null;
3025 }
3026
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003027 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003028 }
3029
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003030 boolean reset() {
3031 boolean wlactive = false;
3032 if (mTimerFull != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003033 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003034 }
3035 if (mTimerPartial != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003036 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003037 }
3038 if (mTimerWindow != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003039 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003040 }
3041 if (!wlactive) {
3042 if (mTimerFull != null) {
3043 mTimerFull.detach();
3044 mTimerFull = null;
3045 }
3046 if (mTimerPartial != null) {
3047 mTimerPartial.detach();
3048 mTimerPartial = null;
3049 }
3050 if (mTimerWindow != null) {
3051 mTimerWindow.detach();
3052 mTimerWindow = null;
3053 }
3054 }
3055 return !wlactive;
3056 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003058 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3059 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
3060 mPartialTimers, unpluggables, in);
3061 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
3062 mFullTimers, unpluggables, in);
3063 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
3064 mWindowTimers, unpluggables, in);
3065 }
3066
3067 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3068 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
3069 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
3070 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
3071 }
3072
3073 @Override
3074 public Timer getWakeTime(int type) {
3075 switch (type) {
3076 case WAKE_TYPE_FULL: return mTimerFull;
3077 case WAKE_TYPE_PARTIAL: return mTimerPartial;
3078 case WAKE_TYPE_WINDOW: return mTimerWindow;
3079 default: throw new IllegalArgumentException("type = " + type);
3080 }
3081 }
3082 }
3083
3084 public final class Sensor extends BatteryStats.Uid.Sensor {
3085 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07003086 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003088 public Sensor(int handle) {
3089 mHandle = handle;
3090 }
3091
Evan Millarc64edde2009-04-18 12:26:32 -07003092 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003093 Parcel in) {
3094 if (in.readInt() == 0) {
3095 return null;
3096 }
3097
Evan Millarc64edde2009-04-18 12:26:32 -07003098 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003099 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003100 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003101 mSensorTimers.put(mHandle, pool);
3102 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003103 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003104 }
3105
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003106 boolean reset() {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003107 if (mTimer.reset(BatteryStatsImpl.this, true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003108 mTimer = null;
3109 return true;
3110 }
3111 return false;
3112 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003114 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3115 mTimer = readTimerFromParcel(unpluggables, in);
3116 }
3117
3118 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3119 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
3120 }
3121
3122 @Override
3123 public Timer getSensorTime() {
3124 return mTimer;
3125 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003126
3127 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003128 public int getHandle() {
3129 return mHandle;
3130 }
3131 }
3132
3133 /**
3134 * The statistics associated with a particular process.
3135 */
3136 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
3137 /**
3138 * Total time (in 1/100 sec) spent executing in user code.
3139 */
3140 long mUserTime;
3141
3142 /**
3143 * Total time (in 1/100 sec) spent executing in kernel code.
3144 */
3145 long mSystemTime;
3146
3147 /**
3148 * Number of times the process has been started.
3149 */
3150 int mStarts;
3151
3152 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003153 * Amount of time the process was running in the foreground.
3154 */
3155 long mForegroundTime;
3156
3157 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003158 * The amount of user time loaded from a previous save.
3159 */
3160 long mLoadedUserTime;
3161
3162 /**
3163 * The amount of system time loaded from a previous save.
3164 */
3165 long mLoadedSystemTime;
3166
3167 /**
3168 * The number of times the process has started from a previous save.
3169 */
3170 int mLoadedStarts;
3171
3172 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003173 * The amount of foreground time loaded from a previous save.
3174 */
3175 long mLoadedForegroundTime;
3176
3177 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 * The amount of user time loaded from the previous run.
3179 */
3180 long mLastUserTime;
3181
3182 /**
3183 * The amount of system time loaded from the previous run.
3184 */
3185 long mLastSystemTime;
3186
3187 /**
3188 * The number of times the process has started from the previous run.
3189 */
3190 int mLastStarts;
3191
3192 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003193 * The amount of foreground time loaded from the previous run
3194 */
3195 long mLastForegroundTime;
3196
3197 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003198 * The amount of user time when last unplugged.
3199 */
3200 long mUnpluggedUserTime;
3201
3202 /**
3203 * The amount of system time when last unplugged.
3204 */
3205 long mUnpluggedSystemTime;
3206
3207 /**
3208 * The number of times the process has started before unplugged.
3209 */
3210 int mUnpluggedStarts;
3211
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003212 /**
3213 * The amount of foreground time since unplugged.
3214 */
3215 long mUnpluggedForegroundTime;
3216
Amith Yamasanie43530a2009-08-21 13:11:37 -07003217 SamplingCounter[] mSpeedBins;
3218
Dianne Hackborn287952c2010-09-22 22:34:31 -07003219 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003221 Proc() {
3222 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003223 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003226 public void unplug(long batteryUptime, long batteryRealtime) {
3227 mUnpluggedUserTime = mUserTime;
3228 mUnpluggedSystemTime = mSystemTime;
3229 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003230 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003231 }
3232
3233 public void plug(long batteryUptime, long batteryRealtime) {
3234 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003235
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003236 void detach() {
3237 mUnpluggables.remove(this);
3238 for (int i = 0; i < mSpeedBins.length; i++) {
3239 SamplingCounter c = mSpeedBins[i];
3240 if (c != null) {
3241 mUnpluggables.remove(c);
3242 mSpeedBins[i] = null;
3243 }
3244 }
3245 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003246
Dianne Hackborn287952c2010-09-22 22:34:31 -07003247 public int countExcessivePowers() {
3248 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003249 }
3250
Dianne Hackborn287952c2010-09-22 22:34:31 -07003251 public ExcessivePower getExcessivePower(int i) {
3252 if (mExcessivePower != null) {
3253 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003254 }
3255 return null;
3256 }
3257
3258 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003259 if (mExcessivePower == null) {
3260 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003261 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07003262 ExcessivePower ew = new ExcessivePower();
3263 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003264 ew.overTime = overTime;
3265 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07003266 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003267 }
3268
Dianne Hackborn287952c2010-09-22 22:34:31 -07003269 public void addExcessiveCpu(long overTime, long usedTime) {
3270 if (mExcessivePower == null) {
3271 mExcessivePower = new ArrayList<ExcessivePower>();
3272 }
3273 ExcessivePower ew = new ExcessivePower();
3274 ew.type = ExcessivePower.TYPE_CPU;
3275 ew.overTime = overTime;
3276 ew.usedTime = usedTime;
3277 mExcessivePower.add(ew);
3278 }
3279
3280 void writeExcessivePowerToParcelLocked(Parcel out) {
3281 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003282 out.writeInt(0);
3283 return;
3284 }
3285
Dianne Hackborn287952c2010-09-22 22:34:31 -07003286 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003287 out.writeInt(N);
3288 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003289 ExcessivePower ew = mExcessivePower.get(i);
3290 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003291 out.writeLong(ew.overTime);
3292 out.writeLong(ew.usedTime);
3293 }
3294 }
3295
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003296 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003297 final int N = in.readInt();
3298 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003299 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003300 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003301 }
3302
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003303 if (N > 10000) {
3304 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
3305 return false;
3306 }
3307
Dianne Hackborn287952c2010-09-22 22:34:31 -07003308 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003309 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003310 ExcessivePower ew = new ExcessivePower();
3311 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003312 ew.overTime = in.readLong();
3313 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07003314 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003315 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003316 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003317 }
3318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003319 void writeToParcelLocked(Parcel out) {
3320 out.writeLong(mUserTime);
3321 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003322 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003323 out.writeInt(mStarts);
3324 out.writeLong(mLoadedUserTime);
3325 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003326 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003327 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328 out.writeLong(mUnpluggedUserTime);
3329 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003330 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003331 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003332
3333 out.writeInt(mSpeedBins.length);
3334 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003335 SamplingCounter c = mSpeedBins[i];
3336 if (c != null) {
3337 out.writeInt(1);
3338 c.writeToParcel(out);
3339 } else {
3340 out.writeInt(0);
3341 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003342 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003343
Dianne Hackborn287952c2010-09-22 22:34:31 -07003344 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003345 }
3346
3347 void readFromParcelLocked(Parcel in) {
3348 mUserTime = in.readLong();
3349 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003350 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003351 mStarts = in.readInt();
3352 mLoadedUserTime = in.readLong();
3353 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003354 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003355 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003356 mLastUserTime = 0;
3357 mLastSystemTime = 0;
3358 mLastForegroundTime = 0;
3359 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003360 mUnpluggedUserTime = in.readLong();
3361 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003362 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003363 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07003364
3365 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003366 int steps = getCpuSpeedSteps();
3367 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07003368 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003369 if (in.readInt() != 0) {
3370 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
3371 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003372 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003373
Dianne Hackborn287952c2010-09-22 22:34:31 -07003374 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375 }
3376
3377 public BatteryStatsImpl getBatteryStats() {
3378 return BatteryStatsImpl.this;
3379 }
3380
3381 public void addCpuTimeLocked(int utime, int stime) {
3382 mUserTime += utime;
3383 mSystemTime += stime;
3384 }
3385
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003386 public void addForegroundTimeLocked(long ttime) {
3387 mForegroundTime += ttime;
3388 }
3389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 public void incStartsLocked() {
3391 mStarts++;
3392 }
3393
3394 @Override
3395 public long getUserTime(int which) {
3396 long val;
3397 if (which == STATS_LAST) {
3398 val = mLastUserTime;
3399 } else {
3400 val = mUserTime;
3401 if (which == STATS_CURRENT) {
3402 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003403 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003404 val -= mUnpluggedUserTime;
3405 }
3406 }
3407 return val;
3408 }
3409
3410 @Override
3411 public long getSystemTime(int which) {
3412 long val;
3413 if (which == STATS_LAST) {
3414 val = mLastSystemTime;
3415 } else {
3416 val = mSystemTime;
3417 if (which == STATS_CURRENT) {
3418 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003419 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003420 val -= mUnpluggedSystemTime;
3421 }
3422 }
3423 return val;
3424 }
3425
3426 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003427 public long getForegroundTime(int which) {
3428 long val;
3429 if (which == STATS_LAST) {
3430 val = mLastForegroundTime;
3431 } else {
3432 val = mForegroundTime;
3433 if (which == STATS_CURRENT) {
3434 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003435 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003436 val -= mUnpluggedForegroundTime;
3437 }
3438 }
3439 return val;
3440 }
3441
3442 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003443 public int getStarts(int which) {
3444 int val;
3445 if (which == STATS_LAST) {
3446 val = mLastStarts;
3447 } else {
3448 val = mStarts;
3449 if (which == STATS_CURRENT) {
3450 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003451 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 val -= mUnpluggedStarts;
3453 }
3454 }
3455 return val;
3456 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003457
3458 /* Called by ActivityManagerService when CPU times are updated. */
3459 public void addSpeedStepTimes(long[] values) {
3460 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003461 long amt = values[i];
3462 if (amt != 0) {
3463 SamplingCounter c = mSpeedBins[i];
3464 if (c == null) {
3465 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
3466 }
3467 c.addCountAtomic(values[i]);
3468 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003469 }
3470 }
3471
3472 @Override
3473 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
3474 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003475 SamplingCounter c = mSpeedBins[speedStep];
3476 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07003477 } else {
3478 return 0;
3479 }
3480 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003481 }
3482
3483 /**
3484 * The statistics associated with a particular package.
3485 */
3486 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
3487 /**
3488 * Number of times this package has done something that could wake up the
3489 * device from sleep.
3490 */
3491 int mWakeups;
3492
3493 /**
3494 * Number of things that could wake up the device loaded from a
3495 * previous save.
3496 */
3497 int mLoadedWakeups;
3498
3499 /**
3500 * Number of things that could wake up the device as of the
3501 * last run.
3502 */
3503 int mLastWakeups;
3504
3505 /**
3506 * Number of things that could wake up the device as of the
3507 * last run.
3508 */
3509 int mUnpluggedWakeups;
3510
3511 /**
3512 * The statics we have collected for this package's services.
3513 */
3514 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
3515
3516 Pkg() {
3517 mUnpluggables.add(this);
3518 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 public void unplug(long batteryUptime, long batteryRealtime) {
3521 mUnpluggedWakeups = mWakeups;
3522 }
3523
3524 public void plug(long batteryUptime, long batteryRealtime) {
3525 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003526
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003527 void detach() {
3528 mUnpluggables.remove(this);
3529 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003531 void readFromParcelLocked(Parcel in) {
3532 mWakeups = in.readInt();
3533 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003534 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003535 mUnpluggedWakeups = in.readInt();
3536
3537 int numServs = in.readInt();
3538 mServiceStats.clear();
3539 for (int m = 0; m < numServs; m++) {
3540 String serviceName = in.readString();
3541 Uid.Pkg.Serv serv = new Serv();
3542 mServiceStats.put(serviceName, serv);
3543
3544 serv.readFromParcelLocked(in);
3545 }
3546 }
3547
3548 void writeToParcelLocked(Parcel out) {
3549 out.writeInt(mWakeups);
3550 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551 out.writeInt(mUnpluggedWakeups);
3552
3553 out.writeInt(mServiceStats.size());
3554 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
3555 out.writeString(servEntry.getKey());
3556 Uid.Pkg.Serv serv = servEntry.getValue();
3557
3558 serv.writeToParcelLocked(out);
3559 }
3560 }
3561
3562 @Override
3563 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
3564 return mServiceStats;
3565 }
3566
3567 @Override
3568 public int getWakeups(int which) {
3569 int val;
3570 if (which == STATS_LAST) {
3571 val = mLastWakeups;
3572 } else {
3573 val = mWakeups;
3574 if (which == STATS_CURRENT) {
3575 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003576 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003577 val -= mUnpluggedWakeups;
3578 }
3579 }
3580
3581 return val;
3582 }
3583
3584 /**
3585 * The statistics associated with a particular service.
3586 */
3587 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
3588 /**
3589 * Total time (ms in battery uptime) the service has been left started.
3590 */
3591 long mStartTime;
3592
3593 /**
3594 * If service has been started and not yet stopped, this is
3595 * when it was started.
3596 */
3597 long mRunningSince;
3598
3599 /**
3600 * True if we are currently running.
3601 */
3602 boolean mRunning;
3603
3604 /**
3605 * Total number of times startService() has been called.
3606 */
3607 int mStarts;
3608
3609 /**
3610 * Total time (ms in battery uptime) the service has been left launched.
3611 */
3612 long mLaunchedTime;
3613
3614 /**
3615 * If service has been launched and not yet exited, this is
3616 * when it was launched (ms in battery uptime).
3617 */
3618 long mLaunchedSince;
3619
3620 /**
3621 * True if we are currently launched.
3622 */
3623 boolean mLaunched;
3624
3625 /**
3626 * Total number times the service has been launched.
3627 */
3628 int mLaunches;
3629
3630 /**
3631 * The amount of time spent started loaded from a previous save
3632 * (ms in battery uptime).
3633 */
3634 long mLoadedStartTime;
3635
3636 /**
3637 * The number of starts loaded from a previous save.
3638 */
3639 int mLoadedStarts;
3640
3641 /**
3642 * The number of launches loaded from a previous save.
3643 */
3644 int mLoadedLaunches;
3645
3646 /**
3647 * The amount of time spent started as of the last run (ms
3648 * in battery uptime).
3649 */
3650 long mLastStartTime;
3651
3652 /**
3653 * The number of starts as of the last run.
3654 */
3655 int mLastStarts;
3656
3657 /**
3658 * The number of launches as of the last run.
3659 */
3660 int mLastLaunches;
3661
3662 /**
3663 * The amount of time spent started when last unplugged (ms
3664 * in battery uptime).
3665 */
3666 long mUnpluggedStartTime;
3667
3668 /**
3669 * The number of starts when last unplugged.
3670 */
3671 int mUnpluggedStarts;
3672
3673 /**
3674 * The number of launches when last unplugged.
3675 */
3676 int mUnpluggedLaunches;
3677
3678 Serv() {
3679 mUnpluggables.add(this);
3680 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003682 public void unplug(long batteryUptime, long batteryRealtime) {
3683 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
3684 mUnpluggedStarts = mStarts;
3685 mUnpluggedLaunches = mLaunches;
3686 }
3687
3688 public void plug(long batteryUptime, long batteryRealtime) {
3689 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003690
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003691 void detach() {
3692 mUnpluggables.remove(this);
3693 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003695 void readFromParcelLocked(Parcel in) {
3696 mStartTime = in.readLong();
3697 mRunningSince = in.readLong();
3698 mRunning = in.readInt() != 0;
3699 mStarts = in.readInt();
3700 mLaunchedTime = in.readLong();
3701 mLaunchedSince = in.readLong();
3702 mLaunched = in.readInt() != 0;
3703 mLaunches = in.readInt();
3704 mLoadedStartTime = in.readLong();
3705 mLoadedStarts = in.readInt();
3706 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003707 mLastStartTime = 0;
3708 mLastStarts = 0;
3709 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 mUnpluggedStartTime = in.readLong();
3711 mUnpluggedStarts = in.readInt();
3712 mUnpluggedLaunches = in.readInt();
3713 }
3714
3715 void writeToParcelLocked(Parcel out) {
3716 out.writeLong(mStartTime);
3717 out.writeLong(mRunningSince);
3718 out.writeInt(mRunning ? 1 : 0);
3719 out.writeInt(mStarts);
3720 out.writeLong(mLaunchedTime);
3721 out.writeLong(mLaunchedSince);
3722 out.writeInt(mLaunched ? 1 : 0);
3723 out.writeInt(mLaunches);
3724 out.writeLong(mLoadedStartTime);
3725 out.writeInt(mLoadedStarts);
3726 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003727 out.writeLong(mUnpluggedStartTime);
3728 out.writeInt(mUnpluggedStarts);
3729 out.writeInt(mUnpluggedLaunches);
3730 }
3731
3732 long getLaunchTimeToNowLocked(long batteryUptime) {
3733 if (!mLaunched) return mLaunchedTime;
3734 return mLaunchedTime + batteryUptime - mLaunchedSince;
3735 }
3736
3737 long getStartTimeToNowLocked(long batteryUptime) {
3738 if (!mRunning) return mStartTime;
3739 return mStartTime + batteryUptime - mRunningSince;
3740 }
3741
3742 public void startLaunchedLocked() {
3743 if (!mLaunched) {
3744 mLaunches++;
3745 mLaunchedSince = getBatteryUptimeLocked();
3746 mLaunched = true;
3747 }
3748 }
3749
3750 public void stopLaunchedLocked() {
3751 if (mLaunched) {
3752 long time = getBatteryUptimeLocked() - mLaunchedSince;
3753 if (time > 0) {
3754 mLaunchedTime += time;
3755 } else {
3756 mLaunches--;
3757 }
3758 mLaunched = false;
3759 }
3760 }
3761
3762 public void startRunningLocked() {
3763 if (!mRunning) {
3764 mStarts++;
3765 mRunningSince = getBatteryUptimeLocked();
3766 mRunning = true;
3767 }
3768 }
3769
3770 public void stopRunningLocked() {
3771 if (mRunning) {
3772 long time = getBatteryUptimeLocked() - mRunningSince;
3773 if (time > 0) {
3774 mStartTime += time;
3775 } else {
3776 mStarts--;
3777 }
3778 mRunning = false;
3779 }
3780 }
3781
3782 public BatteryStatsImpl getBatteryStats() {
3783 return BatteryStatsImpl.this;
3784 }
3785
3786 @Override
3787 public int getLaunches(int which) {
3788 int val;
3789
3790 if (which == STATS_LAST) {
3791 val = mLastLaunches;
3792 } else {
3793 val = mLaunches;
3794 if (which == STATS_CURRENT) {
3795 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003796 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 val -= mUnpluggedLaunches;
3798 }
3799 }
3800
3801 return val;
3802 }
3803
3804 @Override
3805 public long getStartTime(long now, int which) {
3806 long val;
3807 if (which == STATS_LAST) {
3808 val = mLastStartTime;
3809 } else {
3810 val = getStartTimeToNowLocked(now);
3811 if (which == STATS_CURRENT) {
3812 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003813 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003814 val -= mUnpluggedStartTime;
3815 }
3816 }
3817
3818 return val;
3819 }
3820
3821 @Override
3822 public int getStarts(int which) {
3823 int val;
3824 if (which == STATS_LAST) {
3825 val = mLastStarts;
3826 } else {
3827 val = mStarts;
3828 if (which == STATS_CURRENT) {
3829 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003830 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831 val -= mUnpluggedStarts;
3832 }
3833 }
3834
3835 return val;
3836 }
3837 }
3838
3839 public BatteryStatsImpl getBatteryStats() {
3840 return BatteryStatsImpl.this;
3841 }
3842
3843 public void incWakeupsLocked() {
3844 mWakeups++;
3845 }
3846
3847 final Serv newServiceStatsLocked() {
3848 return new Serv();
3849 }
3850 }
3851
3852 /**
3853 * Retrieve the statistics object for a particular process, creating
3854 * if needed.
3855 */
3856 public Proc getProcessStatsLocked(String name) {
3857 Proc ps = mProcessStats.get(name);
3858 if (ps == null) {
3859 ps = new Proc();
3860 mProcessStats.put(name, ps);
3861 }
3862
3863 return ps;
3864 }
3865
Dianne Hackbornb5e31652010-09-07 12:13:55 -07003866 public SparseArray<? extends Pid> getPidStats() {
3867 return mPids;
3868 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003869
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003870 public Pid getPidStatsLocked(int pid) {
3871 Pid p = mPids.get(pid);
3872 if (p == null) {
3873 p = new Pid();
3874 mPids.put(pid, p);
3875 }
3876 return p;
3877 }
3878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 /**
3880 * Retrieve the statistics object for a particular service, creating
3881 * if needed.
3882 */
3883 public Pkg getPackageStatsLocked(String name) {
3884 Pkg ps = mPackageStats.get(name);
3885 if (ps == null) {
3886 ps = new Pkg();
3887 mPackageStats.put(name, ps);
3888 }
3889
3890 return ps;
3891 }
3892
3893 /**
3894 * Retrieve the statistics object for a particular service, creating
3895 * if needed.
3896 */
3897 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
3898 Pkg ps = getPackageStatsLocked(pkg);
3899 Pkg.Serv ss = ps.mServiceStats.get(serv);
3900 if (ss == null) {
3901 ss = ps.newServiceStatsLocked();
3902 ps.mServiceStats.put(serv, ss);
3903 }
3904
3905 return ss;
3906 }
3907
Evan Millarc64edde2009-04-18 12:26:32 -07003908 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003909 Wakelock wl = mWakelockStats.get(name);
3910 if (wl == null) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07003911 final int N = mWakelockStats.size();
3912 if (N > MAX_WAKELOCKS_PER_UID && (mUid != Process.SYSTEM_UID
3913 || N > MAX_WAKELOCKS_PER_UID_IN_SYSTEM)) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08003914 name = BATCHED_WAKELOCK_NAME;
3915 wl = mWakelockStats.get(name);
3916 }
3917 if (wl == null) {
3918 wl = new Wakelock();
3919 mWakelockStats.put(name, wl);
3920 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003921 }
Evan Millarc64edde2009-04-18 12:26:32 -07003922 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003923 switch (type) {
3924 case WAKE_TYPE_PARTIAL:
3925 t = wl.mTimerPartial;
3926 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003927 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
3928 mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003929 wl.mTimerPartial = t;
3930 }
3931 return t;
3932 case WAKE_TYPE_FULL:
3933 t = wl.mTimerFull;
3934 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003935 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
3936 mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003937 wl.mTimerFull = t;
3938 }
3939 return t;
3940 case WAKE_TYPE_WINDOW:
3941 t = wl.mTimerWindow;
3942 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003943 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
3944 mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945 wl.mTimerWindow = t;
3946 }
3947 return t;
3948 default:
3949 throw new IllegalArgumentException("type=" + type);
3950 }
3951 }
3952
Evan Millarc64edde2009-04-18 12:26:32 -07003953 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003954 Sensor se = mSensorStats.get(sensor);
3955 if (se == null) {
3956 if (!create) {
3957 return null;
3958 }
3959 se = new Sensor(sensor);
3960 mSensorStats.put(sensor, se);
3961 }
Evan Millarc64edde2009-04-18 12:26:32 -07003962 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 if (t != null) {
3964 return t;
3965 }
Evan Millarc64edde2009-04-18 12:26:32 -07003966 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003968 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 mSensorTimers.put(sensor, timers);
3970 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003971 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 se.mTimer = t;
3973 return t;
3974 }
3975
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003976 public void noteStartWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003977 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 if (t != null) {
3979 t.startRunningLocked(BatteryStatsImpl.this);
3980 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003981 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003982 Pid p = getPidStatsLocked(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003983 if (p.mWakeStart == 0) {
3984 p.mWakeStart = SystemClock.elapsedRealtime();
3985 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003986 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003987 }
3988
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003989 public void noteStopWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003990 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003991 if (t != null) {
3992 t.stopRunningLocked(BatteryStatsImpl.this);
3993 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003994 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003995 Pid p = mPids.get(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003996 if (p != null && p.mWakeStart != 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003997 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
3998 p.mWakeStart = 0;
3999 }
4000 }
4001 }
4002
4003 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
4004 Proc p = getProcessStatsLocked(proc);
4005 if (p != null) {
4006 p.addExcessiveWake(overTime, usedTime);
4007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004008 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004009
Dianne Hackborn287952c2010-09-22 22:34:31 -07004010 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
4011 Proc p = getProcessStatsLocked(proc);
4012 if (p != null) {
4013 p.addExcessiveCpu(overTime, usedTime);
4014 }
4015 }
4016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004017 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07004018 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004019 if (t != null) {
4020 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004022 }
4023
4024 public void noteStopSensor(int sensor) {
4025 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07004026 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 if (t != null) {
4028 t.stopRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004029 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004030 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004032 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004033 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004034 if (t != null) {
4035 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004037 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004040 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 if (t != null) {
4042 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004043 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004044 }
4045
4046 public BatteryStatsImpl getBatteryStats() {
4047 return BatteryStatsImpl.this;
4048 }
4049 }
4050
4051 public BatteryStatsImpl(String filename) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004052 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004053 mHandler = new MyHandler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004054 mStartCount++;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004055 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004056 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004057 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004058 }
4059 mInputEventCounter = new Counter(mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004060 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
Wink Saville52840902011-02-18 12:40:47 -08004061 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004062 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004063 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004064 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004065 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004066 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004067 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004068 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004069 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004070 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
4071 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
4072 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004073 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004074 initTimes();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004075 mTrackBatteryPastUptime = 0;
4076 mTrackBatteryPastRealtime = 0;
4077 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4078 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4079 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4080 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07004081 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004082 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07004083 mDischargeCurrentLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004084 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004085 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 }
4087
4088 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004089 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004090 mHandler = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004091 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004092 readFromParcel(p);
4093 }
4094
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004095 public void setCallback(BatteryCallback cb) {
4096 mCallback = cb;
4097 }
4098
Amith Yamasanie43530a2009-08-21 13:11:37 -07004099 public void setNumSpeedSteps(int steps) {
4100 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
4101 }
4102
Amith Yamasanif37447b2009-10-08 18:28:01 -07004103 public void setRadioScanningTimeout(long timeout) {
4104 if (mPhoneSignalScanningTimer != null) {
4105 mPhoneSignalScanningTimer.setTimeout(timeout);
4106 }
4107 }
4108
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004109 @Override
4110 public boolean startIteratingOldHistoryLocked() {
4111 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4112 + " pos=" + mHistoryBuffer.dataPosition());
4113 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004114 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004115 mReadOverflow = false;
4116 mIteratingHistory = true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004117 return (mHistoryIterator = mHistory) != null;
4118 }
4119
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004120 @Override
4121 public boolean getNextOldHistoryLocked(HistoryItem out) {
4122 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
4123 if (!end) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004124 mHistoryReadTmp.readDelta(mHistoryBuffer);
4125 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004126 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004127 HistoryItem cur = mHistoryIterator;
4128 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004129 if (!mReadOverflow && !end) {
4130 Slog.w(TAG, "Old history ends before new history!");
4131 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004132 return false;
4133 }
4134 out.setTo(cur);
4135 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004136 if (!mReadOverflow) {
4137 if (end) {
4138 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004139 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004140 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
4141 PrintWriter pw = new PrintWriter(new LogWriter(android.util.Log.WARN, TAG));
4142 pw.println("Histories differ!");
4143 pw.println("Old history:");
4144 (new HistoryPrinter()).printNextItem(pw, out, now);
4145 pw.println("New history:");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004146 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004147 }
4148 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004149 return true;
4150 }
4151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004153 public void finishIteratingOldHistoryLocked() {
4154 mIteratingHistory = false;
4155 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
4156 }
4157
4158 @Override
4159 public boolean startIteratingHistoryLocked() {
4160 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4161 + " pos=" + mHistoryBuffer.dataPosition());
4162 mHistoryBuffer.setDataPosition(0);
4163 mReadOverflow = false;
4164 mIteratingHistory = true;
4165 return mHistoryBuffer.dataSize() > 0;
4166 }
4167
4168 @Override
4169 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004170 final int pos = mHistoryBuffer.dataPosition();
4171 if (pos == 0) {
4172 out.clear();
4173 }
4174 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004175 if (end) {
4176 return false;
4177 }
4178
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004179 out.readDelta(mHistoryBuffer);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004180 return true;
4181 }
4182
4183 @Override
4184 public void finishIteratingHistoryLocked() {
4185 mIteratingHistory = false;
4186 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004187 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004188
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004189 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004190 public long getHistoryBaseTime() {
4191 return mHistoryBaseTime;
4192 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004193
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004194 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004195 public int getStartCount() {
4196 return mStartCount;
4197 }
4198
4199 public boolean isOnBattery() {
4200 return mOnBattery;
4201 }
4202
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004203 public boolean isScreenOn() {
4204 return mScreenOn;
4205 }
4206
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004207 void initTimes() {
4208 mBatteryRealtime = mTrackBatteryPastUptime = 0;
4209 mBatteryUptime = mTrackBatteryPastRealtime = 0;
4210 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4211 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4212 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4213 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
4214 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004215
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004216 void initDischarge() {
4217 mLowDischargeAmountSinceCharge = 0;
4218 mHighDischargeAmountSinceCharge = 0;
4219 mDischargeAmountScreenOn = 0;
4220 mDischargeAmountScreenOnSinceCharge = 0;
4221 mDischargeAmountScreenOff = 0;
4222 mDischargeAmountScreenOffSinceCharge = 0;
4223 }
4224
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004225 public void resetAllStatsLocked() {
4226 mStartCount = 0;
4227 initTimes();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004228 mScreenOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004229 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004230 mScreenBrightnessTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004231 }
4232 mInputEventCounter.reset(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004233 mPhoneOnTimer.reset(this, false);
4234 mAudioOnTimer.reset(this, false);
4235 mVideoOnTimer.reset(this, false);
Wink Saville52840902011-02-18 12:40:47 -08004236 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004237 mPhoneSignalStrengthsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004238 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004239 mPhoneSignalScanningTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004240 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004241 mPhoneDataConnectionsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004242 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004243 mWifiOnTimer.reset(this, false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004244 mGlobalWifiRunningTimer.reset(this, false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004245 mBluetoothOnTimer.reset(this, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004246
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004247 for (int i=0; i<mUidStats.size(); i++) {
4248 if (mUidStats.valueAt(i).reset()) {
4249 mUidStats.remove(mUidStats.keyAt(i));
4250 i--;
4251 }
4252 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004253
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004254 if (mKernelWakelockStats.size() > 0) {
4255 for (SamplingTimer timer : mKernelWakelockStats.values()) {
4256 mUnpluggables.remove(timer);
4257 }
4258 mKernelWakelockStats.clear();
4259 }
4260
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004261 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004262
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004263 clearHistoryLocked();
4264 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004265
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004266 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004267 if (oldScreenOn) {
4268 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
4269 if (diff > 0) {
4270 mDischargeAmountScreenOn += diff;
4271 mDischargeAmountScreenOnSinceCharge += diff;
4272 }
4273 } else {
4274 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
4275 if (diff > 0) {
4276 mDischargeAmountScreenOff += diff;
4277 mDischargeAmountScreenOffSinceCharge += diff;
4278 }
4279 }
4280 if (newScreenOn) {
4281 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
4282 mDischargeScreenOffUnplugLevel = 0;
4283 } else {
4284 mDischargeScreenOnUnplugLevel = 0;
4285 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
4286 }
4287 }
4288
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004289 void setOnBattery(boolean onBattery, int oldStatus, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004290 synchronized(this) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004291 setOnBatteryLocked(onBattery, oldStatus, level);
4292 }
4293 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004294
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004295 void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
4296 boolean doWrite = false;
4297 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
4298 m.arg1 = onBattery ? 1 : 0;
4299 mHandler.sendMessage(m);
4300 mOnBattery = mOnBatteryInternal = onBattery;
4301
4302 long uptime = SystemClock.uptimeMillis() * 1000;
4303 long mSecRealtime = SystemClock.elapsedRealtime();
4304 long realtime = mSecRealtime * 1000;
4305 if (onBattery) {
4306 // We will reset our status if we are unplugging after the
4307 // battery was last full, or the level is at 100, or
4308 // we have gone through a significant charge (from a very low
4309 // level to a now very high level).
4310 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
4311 || level >= 90
4312 || (mDischargeCurrentLevel < 20 && level >= 80)) {
4313 doWrite = true;
4314 resetAllStatsLocked();
4315 mDischargeStartLevel = level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004316 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004317 updateKernelWakelocksLocked();
4318 mHistoryCur.batteryLevel = (byte)level;
4319 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4320 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
4321 + Integer.toHexString(mHistoryCur.states));
4322 addHistoryRecordLocked(mSecRealtime);
4323 mTrackBatteryUptimeStart = uptime;
4324 mTrackBatteryRealtimeStart = realtime;
4325 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
4326 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
4327 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
4328 if (mScreenOn) {
4329 mDischargeScreenOnUnplugLevel = level;
4330 mDischargeScreenOffUnplugLevel = 0;
4331 } else {
4332 mDischargeScreenOnUnplugLevel = 0;
4333 mDischargeScreenOffUnplugLevel = level;
4334 }
4335 mDischargeAmountScreenOn = 0;
4336 mDischargeAmountScreenOff = 0;
4337 doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
4338 } else {
4339 updateKernelWakelocksLocked();
4340 mHistoryCur.batteryLevel = (byte)level;
4341 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4342 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
4343 + Integer.toHexString(mHistoryCur.states));
4344 addHistoryRecordLocked(mSecRealtime);
4345 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
4346 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
4347 mDischargeCurrentLevel = level;
4348 if (level < mDischargeUnplugLevel) {
4349 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
4350 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
4351 }
4352 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
4353 doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
4354 }
4355 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
4356 if (mFile != null) {
4357 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004358 }
4359 }
4360 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004361
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004362 // This should probably be exposed in the API, though it's not critical
4363 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004364
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004365 public void setBatteryState(int status, int health, int plugType, int level,
4366 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004367 synchronized(this) {
4368 boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
4369 int oldStatus = mHistoryCur.batteryStatus;
4370 if (!mHaveBatteryLevel) {
4371 mHaveBatteryLevel = true;
4372 // We start out assuming that the device is plugged in (not
4373 // on battery). If our first report is now that we are indeed
4374 // plugged in, then twiddle our state to correctly reflect that
4375 // since we won't be going through the full setOnBattery().
4376 if (onBattery == mOnBattery) {
4377 if (onBattery) {
4378 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4379 } else {
4380 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4381 }
4382 }
4383 oldStatus = status;
4384 }
4385 if (onBattery) {
4386 mDischargeCurrentLevel = level;
4387 mRecordingHistory = true;
4388 }
4389 if (onBattery != mOnBattery) {
4390 mHistoryCur.batteryLevel = (byte)level;
4391 mHistoryCur.batteryStatus = (byte)status;
4392 mHistoryCur.batteryHealth = (byte)health;
4393 mHistoryCur.batteryPlugType = (byte)plugType;
4394 mHistoryCur.batteryTemperature = (char)temp;
4395 mHistoryCur.batteryVoltage = (char)volt;
4396 setOnBatteryLocked(onBattery, oldStatus, level);
4397 } else {
4398 boolean changed = false;
4399 if (mHistoryCur.batteryLevel != level) {
4400 mHistoryCur.batteryLevel = (byte)level;
4401 changed = true;
4402 }
4403 if (mHistoryCur.batteryStatus != status) {
4404 mHistoryCur.batteryStatus = (byte)status;
4405 changed = true;
4406 }
4407 if (mHistoryCur.batteryHealth != health) {
4408 mHistoryCur.batteryHealth = (byte)health;
4409 changed = true;
4410 }
4411 if (mHistoryCur.batteryPlugType != plugType) {
4412 mHistoryCur.batteryPlugType = (byte)plugType;
4413 changed = true;
4414 }
4415 if (temp >= (mHistoryCur.batteryTemperature+10)
4416 || temp <= (mHistoryCur.batteryTemperature-10)) {
4417 mHistoryCur.batteryTemperature = (char)temp;
4418 changed = true;
4419 }
4420 if (volt > (mHistoryCur.batteryVoltage+20)
4421 || volt < (mHistoryCur.batteryVoltage-20)) {
4422 mHistoryCur.batteryVoltage = (char)volt;
4423 changed = true;
4424 }
4425 if (changed) {
4426 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004427 }
4428 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004429 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
4430 // We don't record history while we are plugged in and fully charged.
4431 // The next time we are unplugged, history will be cleared.
4432 mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004433 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004434 }
Evan Millar633a1742009-04-02 16:36:33 -07004435 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004436
Evan Millarc64edde2009-04-18 12:26:32 -07004437 public void updateKernelWakelocksLocked() {
4438 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004439
Marco Nelissend8593312009-04-30 14:45:06 -07004440 if (m == null) {
4441 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004442 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07004443 return;
4444 }
4445
Evan Millarc64edde2009-04-18 12:26:32 -07004446 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
4447 String name = ent.getKey();
4448 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004449
Evan Millarc64edde2009-04-18 12:26:32 -07004450 SamplingTimer kwlt = mKernelWakelockStats.get(name);
4451 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004452 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07004453 true /* track reported values */);
4454 mKernelWakelockStats.put(name, kwlt);
4455 }
4456 kwlt.updateCurrentReportedCount(kws.mCount);
4457 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
4458 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
4459 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004460
Evan Millarc64edde2009-04-18 12:26:32 -07004461 if (m.size() != mKernelWakelockStats.size()) {
4462 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
4463 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4464 SamplingTimer st = ent.getValue();
4465 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
4466 st.setStale();
4467 }
4468 }
4469 }
4470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004471
4472 public long getAwakeTimeBattery() {
4473 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
4474 }
4475
4476 public long getAwakeTimePlugged() {
4477 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
4478 }
4479
4480 @Override
4481 public long computeUptime(long curTime, int which) {
4482 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004483 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 case STATS_LAST: return mLastUptime;
4485 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004486 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004487 }
4488 return 0;
4489 }
4490
4491 @Override
4492 public long computeRealtime(long curTime, int which) {
4493 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004494 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 case STATS_LAST: return mLastRealtime;
4496 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004497 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 }
4499 return 0;
4500 }
4501
4502 @Override
4503 public long computeBatteryUptime(long curTime, int which) {
4504 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004505 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004506 return mBatteryUptime + getBatteryUptime(curTime);
4507 case STATS_LAST:
4508 return mBatteryLastUptime;
4509 case STATS_CURRENT:
4510 return getBatteryUptime(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004511 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
4513 }
4514 return 0;
4515 }
4516
4517 @Override
4518 public long computeBatteryRealtime(long curTime, int which) {
4519 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004520 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
4522 case STATS_LAST:
4523 return mBatteryLastRealtime;
4524 case STATS_CURRENT:
4525 return getBatteryRealtimeLocked(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004526 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004527 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
4528 }
4529 return 0;
4530 }
4531
4532 long getBatteryUptimeLocked(long curTime) {
4533 long time = mTrackBatteryPastUptime;
4534 if (mOnBatteryInternal) {
4535 time += curTime - mTrackBatteryUptimeStart;
4536 }
4537 return time;
4538 }
4539
4540 long getBatteryUptimeLocked() {
4541 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
4542 }
4543
4544 @Override
4545 public long getBatteryUptime(long curTime) {
4546 return getBatteryUptimeLocked(curTime);
4547 }
4548
4549 long getBatteryRealtimeLocked(long curTime) {
4550 long time = mTrackBatteryPastRealtime;
4551 if (mOnBatteryInternal) {
4552 time += curTime - mTrackBatteryRealtimeStart;
4553 }
4554 return time;
4555 }
4556
4557 @Override
4558 public long getBatteryRealtime(long curTime) {
4559 return getBatteryRealtimeLocked(curTime);
4560 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004561
4562 private long getTcpBytes(long current, long[] dataBytes, int which) {
4563 if (which == STATS_LAST) {
4564 return dataBytes[STATS_LAST];
4565 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004566 if (which == STATS_SINCE_UNPLUGGED) {
4567 if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004568 return dataBytes[STATS_LAST];
4569 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004570 return current - dataBytes[STATS_SINCE_UNPLUGGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004571 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004572 } else if (which == STATS_SINCE_CHARGED) {
4573 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004574 }
4575 return current - dataBytes[STATS_CURRENT];
4576 }
4577 }
4578
4579 /** Only STATS_UNPLUGGED works properly */
4580 public long getMobileTcpBytesSent(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004581 final long mobileTxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).txBytes;
4582 return getTcpBytes(mobileTxBytes, mMobileDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004583 }
4584
4585 /** Only STATS_UNPLUGGED works properly */
4586 public long getMobileTcpBytesReceived(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004587 final long mobileRxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).rxBytes;
4588 return getTcpBytes(mobileRxBytes, mMobileDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004589 }
4590
4591 /** Only STATS_UNPLUGGED works properly */
4592 public long getTotalTcpBytesSent(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004593 final long totalTxBytes = getNetworkStatsSummary().getTotal(null).txBytes;
4594 return getTcpBytes(totalTxBytes, mTotalDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004595 }
4596
4597 /** Only STATS_UNPLUGGED works properly */
4598 public long getTotalTcpBytesReceived(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004599 final long totalRxBytes = getNetworkStatsSummary().getTotal(null).rxBytes;
4600 return getTcpBytes(totalRxBytes, mTotalDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004601 }
4602
The Android Open Source Project10592532009-03-18 17:39:46 -07004603 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004604 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004605 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004606 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004607 }
4608 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004609
Evan Millar633a1742009-04-02 16:36:33 -07004610 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004611 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004612 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004613
The Android Open Source Project10592532009-03-18 17:39:46 -07004614 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004615 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004616 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004617 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004618 }
4619 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004620
Evan Millar633a1742009-04-02 16:36:33 -07004621 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004622 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004624
Amith Yamasanie43530a2009-08-21 13:11:37 -07004625 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004626 public int getLowDischargeAmountSinceCharge() {
4627 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004628 int val = mLowDischargeAmountSinceCharge;
4629 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4630 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
4631 }
4632 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004633 }
4634 }
4635
4636 @Override
4637 public int getHighDischargeAmountSinceCharge() {
4638 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004639 int val = mHighDischargeAmountSinceCharge;
4640 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4641 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
4642 }
4643 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004644 }
4645 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004646
4647 public int getDischargeAmountScreenOn() {
4648 synchronized(this) {
4649 int val = mDischargeAmountScreenOn;
4650 if (mOnBattery && mScreenOn
4651 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4652 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4653 }
4654 return val;
4655 }
4656 }
4657
4658 public int getDischargeAmountScreenOnSinceCharge() {
4659 synchronized(this) {
4660 int val = mDischargeAmountScreenOnSinceCharge;
4661 if (mOnBattery && mScreenOn
4662 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4663 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4664 }
4665 return val;
4666 }
4667 }
4668
4669 public int getDischargeAmountScreenOff() {
4670 synchronized(this) {
4671 int val = mDischargeAmountScreenOff;
4672 if (mOnBattery && !mScreenOn
4673 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4674 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4675 }
4676 return val;
4677 }
4678 }
4679
4680 public int getDischargeAmountScreenOffSinceCharge() {
4681 synchronized(this) {
4682 int val = mDischargeAmountScreenOffSinceCharge;
4683 if (mOnBattery && !mScreenOn
4684 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4685 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4686 }
4687 return val;
4688 }
4689 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004690
4691 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07004692 public int getCpuSpeedSteps() {
4693 return sNumSpeedSteps;
4694 }
4695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004696 /**
4697 * Retrieve the statistics object for a particular uid, creating if needed.
4698 */
4699 public Uid getUidStatsLocked(int uid) {
4700 Uid u = mUidStats.get(uid);
4701 if (u == null) {
4702 u = new Uid(uid);
4703 mUidStats.put(uid, u);
4704 }
4705 return u;
4706 }
4707
4708 /**
4709 * Remove the statistics object for a particular uid.
4710 */
4711 public void removeUidStatsLocked(int uid) {
4712 mUidStats.remove(uid);
4713 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004715 /**
4716 * Retrieve the statistics object for a particular process, creating
4717 * if needed.
4718 */
4719 public Uid.Proc getProcessStatsLocked(int uid, String name) {
4720 Uid u = getUidStatsLocked(uid);
4721 return u.getProcessStatsLocked(name);
4722 }
4723
4724 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004725 * Retrieve the statistics object for a particular process, given
4726 * the name of the process.
4727 * @param name process name
4728 * @return the statistics object for the process
4729 */
Amith Yamasani819f9282009-06-24 23:18:15 -07004730 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004731 int uid;
4732 if (mUidCache.containsKey(name)) {
4733 uid = mUidCache.get(name);
4734 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07004735 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004736 mUidCache.put(name, uid);
4737 }
4738 Uid u = getUidStatsLocked(uid);
4739 return u.getProcessStatsLocked(name);
4740 }
4741
4742 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004743 * Retrieve the statistics object for a particular process, creating
4744 * if needed.
4745 */
4746 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
4747 Uid u = getUidStatsLocked(uid);
4748 return u.getPackageStatsLocked(pkg);
4749 }
4750
4751 /**
4752 * Retrieve the statistics object for a particular service, creating
4753 * if needed.
4754 */
4755 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
4756 Uid u = getUidStatsLocked(uid);
4757 return u.getServiceStatsLocked(pkg, name);
4758 }
4759
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004760 /**
4761 * Massage data to distribute any reasonable work down to more specific
4762 * owners. Must only be called on a dead BatteryStats object!
4763 */
4764 public void distributeWorkLocked(int which) {
4765 // Aggregate all CPU time associated with WIFI.
4766 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
4767 if (wifiUid != null) {
4768 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
4769 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
4770 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
4771 for (int i=0; i<mUidStats.size(); i++) {
4772 Uid uid = mUidStats.valueAt(i);
4773 if (uid.mUid != Process.WIFI_UID) {
4774 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
4775 if (uidRunningTime > 0) {
4776 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
4777 long time = proc.getUserTime(which);
4778 time = (time*uidRunningTime)/totalRunningTime;
4779 uidProc.mUserTime += time;
4780 proc.mUserTime -= time;
4781 time = proc.getSystemTime(which);
4782 time = (time*uidRunningTime)/totalRunningTime;
4783 uidProc.mSystemTime += time;
4784 proc.mSystemTime -= time;
4785 time = proc.getForegroundTime(which);
4786 time = (time*uidRunningTime)/totalRunningTime;
4787 uidProc.mForegroundTime += time;
4788 proc.mForegroundTime -= time;
4789 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
4790 SamplingCounter sc = proc.mSpeedBins[sb];
4791 if (sc != null) {
4792 time = sc.getCountLocked(which);
4793 time = (time*uidRunningTime)/totalRunningTime;
4794 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
4795 if (uidSc == null) {
4796 uidSc = new SamplingCounter(mUnpluggables);
4797 uidProc.mSpeedBins[sb] = uidSc;
4798 }
4799 uidSc.mCount.addAndGet((int)time);
4800 sc.mCount.addAndGet((int)-time);
4801 }
4802 }
4803 totalRunningTime -= uidRunningTime;
4804 }
4805 }
4806 }
4807 }
4808 }
4809 }
4810
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004811 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004812 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004813 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004814 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004815
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004816 Parcel mPendingWrite = null;
4817 final ReentrantLock mWriteLock = new ReentrantLock();
4818
4819 public void writeAsyncLocked() {
4820 writeLocked(false);
4821 }
4822
4823 public void writeSyncLocked() {
4824 writeLocked(true);
4825 }
4826
4827 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004828 if (mFile == null) {
4829 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004830 return;
4831 }
4832
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004833 if (mShuttingDown) {
4834 return;
4835 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004836
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004837 Parcel out = Parcel.obtain();
4838 writeSummaryToParcel(out);
4839 mLastWriteTime = SystemClock.elapsedRealtime();
4840
4841 if (mPendingWrite != null) {
4842 mPendingWrite.recycle();
4843 }
4844 mPendingWrite = out;
4845
4846 if (sync) {
4847 commitPendingDataToDisk();
4848 } else {
4849 Thread thr = new Thread("BatteryStats-Write") {
4850 @Override
4851 public void run() {
4852 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
4853 commitPendingDataToDisk();
4854 }
4855 };
4856 thr.start();
4857 }
4858 }
4859
4860 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004861 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004862 synchronized (this) {
4863 next = mPendingWrite;
4864 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004865 if (next == null) {
4866 return;
4867 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004868
4869 mWriteLock.lock();
4870 }
4871
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004872 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004873 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004874 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004875 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07004876 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004877 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004878 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004879 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004880 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004881 mFile.rollback();
4882 } finally {
4883 next.recycle();
4884 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07004885 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004886 }
4887
4888 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
4889 int pos = 0;
4890 int avail = stream.available();
4891 byte[] data = new byte[avail];
4892 while (true) {
4893 int amt = stream.read(data, pos, data.length-pos);
4894 //Log.i("foo", "Read " + amt + " bytes at " + pos
4895 // + " of avail " + data.length);
4896 if (amt <= 0) {
4897 //Log.i("foo", "**** FINISHED READING: pos=" + pos
4898 // + " len=" + data.length);
4899 return data;
4900 }
4901 pos += amt;
4902 avail = stream.available();
4903 if (avail > data.length-pos) {
4904 byte[] newData = new byte[pos+avail];
4905 System.arraycopy(data, 0, newData, 0, pos);
4906 data = newData;
4907 }
4908 }
4909 }
4910
4911 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004912 if (mFile == null) {
4913 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 return;
4915 }
4916
4917 mUidStats.clear();
4918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004920 File file = mFile.chooseForRead();
4921 if (!file.exists()) {
4922 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004923 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004924 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925
4926 byte[] raw = readFully(stream);
4927 Parcel in = Parcel.obtain();
4928 in.unmarshall(raw, 0, raw.length);
4929 in.setDataPosition(0);
4930 stream.close();
4931
4932 readSummaryFromParcel(in);
4933 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004934 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004935 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004936
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004937 long now = SystemClock.elapsedRealtime();
Dianne Hackborne8c88e62011-08-17 19:09:09 -07004938 if (USE_OLD_HISTORY) {
4939 addHistoryRecordLocked(now, HistoryItem.CMD_START);
4940 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004941 addHistoryBufferLocked(now, HistoryItem.CMD_START);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004942 }
4943
4944 public int describeContents() {
4945 return 0;
4946 }
4947
Dianne Hackbornae384452011-06-28 12:33:48 -07004948 void readHistory(Parcel in, boolean andOldHistory) {
4949 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004950
4951 mHistoryBuffer.setDataSize(0);
4952 mHistoryBuffer.setDataPosition(0);
4953
4954 int bufSize = in.readInt();
4955 int curPos = in.dataPosition();
4956 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
4957 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
4958 } else if ((bufSize&~3) != bufSize) {
4959 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
4960 } else {
4961 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
4962 + " bytes at " + curPos);
4963 mHistoryBuffer.appendFrom(in, curPos, bufSize);
4964 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004965 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004966
Dianne Hackbornae384452011-06-28 12:33:48 -07004967 if (andOldHistory) {
4968 readOldHistory(in);
4969 }
4970
4971 if (DEBUG_HISTORY) {
4972 StringBuilder sb = new StringBuilder(128);
4973 sb.append("****************** OLD mHistoryBaseTime: ");
4974 TimeUtils.formatDuration(mHistoryBaseTime, sb);
4975 Slog.i(TAG, sb.toString());
4976 }
4977 mHistoryBaseTime = historyBaseTime;
4978 if (DEBUG_HISTORY) {
4979 StringBuilder sb = new StringBuilder(128);
4980 sb.append("****************** NEW mHistoryBaseTime: ");
4981 TimeUtils.formatDuration(mHistoryBaseTime, sb);
4982 Slog.i(TAG, sb.toString());
4983 }
4984
4985 // We are just arbitrarily going to insert 1 minute from the sample of
4986 // the last run until samples in this run.
4987 if (mHistoryBaseTime > 0) {
4988 long oldnow = SystemClock.elapsedRealtime();
4989 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000;
4990 if (DEBUG_HISTORY) {
4991 StringBuilder sb = new StringBuilder(128);
4992 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
4993 TimeUtils.formatDuration(mHistoryBaseTime, sb);
4994 Slog.i(TAG, sb.toString());
4995 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07004996 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004997 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004998
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004999 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005000 if (!USE_OLD_HISTORY) {
5001 return;
5002 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005003 mHistory = mHistoryEnd = mHistoryCache = null;
5004 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07005005 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005006 HistoryItem rec = new HistoryItem(time, in);
5007 addHistoryRecordLocked(rec);
5008 }
5009 }
5010
Dianne Hackbornae384452011-06-28 12:33:48 -07005011 void writeHistory(Parcel out, boolean andOldHistory) {
5012 if (DEBUG_HISTORY) {
5013 StringBuilder sb = new StringBuilder(128);
5014 sb.append("****************** WRITING mHistoryBaseTime: ");
5015 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5016 sb.append(" mLastHistoryTime: ");
5017 TimeUtils.formatDuration(mLastHistoryTime, sb);
5018 Slog.i(TAG, sb.toString());
5019 }
5020 out.writeLong(mHistoryBaseTime + mLastHistoryTime);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005021 out.writeInt(mHistoryBuffer.dataSize());
5022 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
5023 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
5024 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07005025
5026 if (andOldHistory) {
5027 writeOldHistory(out);
5028 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005029 }
5030
5031 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005032 if (!USE_OLD_HISTORY) {
5033 return;
5034 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005035 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005036 while (rec != null) {
5037 if (rec.time >= 0) rec.writeToParcel(out, 0);
5038 rec = rec.next;
5039 }
5040 out.writeLong(-1);
5041 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005043 private void readSummaryFromParcel(Parcel in) {
5044 final int version = in.readInt();
5045 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005046 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005047 + ", expected " + VERSION + "; erasing old stats");
5048 return;
5049 }
5050
Dianne Hackbornae384452011-06-28 12:33:48 -07005051 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005053 mStartCount = in.readInt();
5054 mBatteryUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005055 mBatteryRealtime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005056 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005057 mRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005058 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005059 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005060 mLowDischargeAmountSinceCharge = in.readInt();
5061 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005062 mDischargeAmountScreenOnSinceCharge = in.readInt();
5063 mDischargeAmountScreenOffSinceCharge = in.readInt();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005065 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005067 mScreenOn = false;
5068 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005069 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5070 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
5071 }
5072 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005073 mPhoneOn = false;
5074 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08005075 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005076 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
5077 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005078 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005079 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5080 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
5081 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005082 mWifiOn = false;
5083 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005084 mGlobalWifiRunning = false;
5085 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005086 mBluetoothOn = false;
5087 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005088
Evan Millarc64edde2009-04-18 12:26:32 -07005089 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005090 if (NKW > 10000) {
5091 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
5092 return;
5093 }
Evan Millarc64edde2009-04-18 12:26:32 -07005094 for (int ikw = 0; ikw < NKW; ikw++) {
5095 if (in.readInt() != 0) {
5096 String kwltName = in.readString();
5097 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
5098 }
5099 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005100
5101 sNumSpeedSteps = in.readInt();
5102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005103 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005104 if (NU > 10000) {
5105 Slog.w(TAG, "File corrupt: too many uids " + NU);
5106 return;
5107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005108 for (int iu = 0; iu < NU; iu++) {
5109 int uid = in.readInt();
5110 Uid u = new Uid(uid);
5111 mUidStats.put(uid, u);
5112
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005113 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005114 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005115 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005116 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005117 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005118 if (in.readInt() != 0) {
5119 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
5120 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005121 u.mScanWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005122 if (in.readInt() != 0) {
5123 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
5124 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005125 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005126 if (in.readInt() != 0) {
5127 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
5128 }
5129 u.mAudioTurnedOn = false;
5130 if (in.readInt() != 0) {
5131 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
5132 }
5133 u.mVideoTurnedOn = false;
5134 if (in.readInt() != 0) {
5135 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
5136 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005137
Dianne Hackborn617f8772009-03-31 15:04:46 -07005138 if (in.readInt() != 0) {
5139 if (u.mUserActivityCounters == null) {
5140 u.initUserActivityLocked();
5141 }
5142 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5143 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
5144 }
5145 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005147 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005148 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005149 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
5150 return;
5151 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005152 for (int iw = 0; iw < NW; iw++) {
5153 String wlName = in.readString();
5154 if (in.readInt() != 0) {
5155 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
5156 }
5157 if (in.readInt() != 0) {
5158 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
5159 }
5160 if (in.readInt() != 0) {
5161 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
5162 }
5163 }
5164
5165 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005166 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005167 Slog.w(TAG, "File corrupt: too many sensors " + NP);
5168 return;
5169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005170 for (int is = 0; is < NP; is++) {
5171 int seNumber = in.readInt();
5172 if (in.readInt() != 0) {
5173 u.getSensorTimerLocked(seNumber, true)
5174 .readSummaryFromParcelLocked(in);
5175 }
5176 }
5177
5178 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005179 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005180 Slog.w(TAG, "File corrupt: too many processes " + NP);
5181 return;
5182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005183 for (int ip = 0; ip < NP; ip++) {
5184 String procName = in.readString();
5185 Uid.Proc p = u.getProcessStatsLocked(procName);
5186 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005187 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005188 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005189 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005190 if (NSB > 100) {
5191 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
5192 return;
5193 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005194 p.mSpeedBins = new SamplingCounter[NSB];
5195 for (int i=0; i<NSB; i++) {
5196 if (in.readInt() != 0) {
5197 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables);
5198 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
5199 }
5200 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005201 if (!p.readExcessivePowerFromParcelLocked(in)) {
5202 return;
5203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005204 }
5205
5206 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005207 if (NP > 10000) {
5208 Slog.w(TAG, "File corrupt: too many packages " + NP);
5209 return;
5210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005211 for (int ip = 0; ip < NP; ip++) {
5212 String pkgName = in.readString();
5213 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
5214 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005215 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005216 if (NS > 1000) {
5217 Slog.w(TAG, "File corrupt: too many services " + NS);
5218 return;
5219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005220 for (int is = 0; is < NS; is++) {
5221 String servName = in.readString();
5222 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
5223 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005224 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005225 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226 }
5227 }
5228
5229 u.mLoadedTcpBytesReceived = in.readLong();
5230 u.mLoadedTcpBytesSent = in.readLong();
5231 }
5232 }
5233
5234 /**
5235 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
5236 * disk. This format does not allow a lossless round-trip.
5237 *
5238 * @param out the Parcel to be written to.
5239 */
5240 public void writeSummaryToParcel(Parcel out) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005241 // Need to update with current kernel wake lock counts.
5242 updateKernelWakelocksLocked();
5243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005244 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
5245 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
5246 final long NOW = getBatteryUptimeLocked(NOW_SYS);
5247 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
5248
5249 out.writeInt(VERSION);
5250
Dianne Hackbornae384452011-06-28 12:33:48 -07005251 writeHistory(out, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005253 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005254 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005255 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005256 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005257 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005258 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005259 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08005260 out.writeInt(getLowDischargeAmountSinceCharge());
5261 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005262 out.writeInt(getDischargeAmountScreenOnSinceCharge());
5263 out.writeInt(getDischargeAmountScreenOffSinceCharge());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005264
5265 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005266 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5267 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5268 }
5269 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005270 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Wink Saville52840902011-02-18 12:40:47 -08005271 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005272 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5273 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005274 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005275 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5276 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5277 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005278 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005279 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07005280 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005281
Evan Millarc64edde2009-04-18 12:26:32 -07005282 out.writeInt(mKernelWakelockStats.size());
5283 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5284 Timer kwlt = ent.getValue();
5285 if (kwlt != null) {
5286 out.writeInt(1);
5287 out.writeString(ent.getKey());
5288 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
5289 } else {
5290 out.writeInt(0);
5291 }
5292 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005293
Amith Yamasanie43530a2009-08-21 13:11:37 -07005294 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005295 final int NU = mUidStats.size();
5296 out.writeInt(NU);
5297 for (int iu = 0; iu < NU; iu++) {
5298 out.writeInt(mUidStats.keyAt(iu));
5299 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005300
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005301 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005302 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005303 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005304 } else {
5305 out.writeInt(0);
5306 }
5307 if (u.mFullWifiLockTimer != null) {
5308 out.writeInt(1);
5309 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5310 } else {
5311 out.writeInt(0);
5312 }
5313 if (u.mScanWifiLockTimer != null) {
5314 out.writeInt(1);
5315 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5316 } else {
5317 out.writeInt(0);
5318 }
5319 if (u.mWifiMulticastTimer != null) {
5320 out.writeInt(1);
5321 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5322 } else {
5323 out.writeInt(0);
5324 }
5325 if (u.mAudioTurnedOnTimer != null) {
5326 out.writeInt(1);
5327 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5328 } else {
5329 out.writeInt(0);
5330 }
5331 if (u.mVideoTurnedOnTimer != null) {
5332 out.writeInt(1);
5333 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5334 } else {
5335 out.writeInt(0);
5336 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337
Dianne Hackborn617f8772009-03-31 15:04:46 -07005338 if (u.mUserActivityCounters == null) {
5339 out.writeInt(0);
5340 } else {
5341 out.writeInt(1);
5342 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5343 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
5344 }
5345 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005347 int NW = u.mWakelockStats.size();
5348 out.writeInt(NW);
5349 if (NW > 0) {
5350 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
5351 : u.mWakelockStats.entrySet()) {
5352 out.writeString(ent.getKey());
5353 Uid.Wakelock wl = ent.getValue();
5354 if (wl.mTimerFull != null) {
5355 out.writeInt(1);
5356 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
5357 } else {
5358 out.writeInt(0);
5359 }
5360 if (wl.mTimerPartial != null) {
5361 out.writeInt(1);
5362 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
5363 } else {
5364 out.writeInt(0);
5365 }
5366 if (wl.mTimerWindow != null) {
5367 out.writeInt(1);
5368 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
5369 } else {
5370 out.writeInt(0);
5371 }
5372 }
5373 }
5374
5375 int NSE = u.mSensorStats.size();
5376 out.writeInt(NSE);
5377 if (NSE > 0) {
5378 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
5379 : u.mSensorStats.entrySet()) {
5380 out.writeInt(ent.getKey());
5381 Uid.Sensor se = ent.getValue();
5382 if (se.mTimer != null) {
5383 out.writeInt(1);
5384 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5385 } else {
5386 out.writeInt(0);
5387 }
5388 }
5389 }
5390
5391 int NP = u.mProcessStats.size();
5392 out.writeInt(NP);
5393 if (NP > 0) {
5394 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
5395 : u.mProcessStats.entrySet()) {
5396 out.writeString(ent.getKey());
5397 Uid.Proc ps = ent.getValue();
5398 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005399 out.writeLong(ps.mSystemTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005400 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005401 final int N = ps.mSpeedBins.length;
5402 out.writeInt(N);
5403 for (int i=0; i<N; i++) {
5404 if (ps.mSpeedBins[i] != null) {
5405 out.writeInt(1);
5406 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
5407 } else {
5408 out.writeInt(0);
5409 }
5410 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005411 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005412 }
5413 }
5414
5415 NP = u.mPackageStats.size();
5416 out.writeInt(NP);
5417 if (NP > 0) {
5418 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
5419 : u.mPackageStats.entrySet()) {
5420 out.writeString(ent.getKey());
5421 Uid.Pkg ps = ent.getValue();
5422 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005423 final int NS = ps.mServiceStats.size();
5424 out.writeInt(NS);
5425 if (NS > 0) {
5426 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
5427 : ps.mServiceStats.entrySet()) {
5428 out.writeString(sent.getKey());
5429 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
5430 long time = ss.getStartTimeToNowLocked(NOW);
5431 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005433 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005434 }
5435 }
5436 }
5437 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005438
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005439 out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED));
5440 out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005441 }
5442 }
5443
5444 public void readFromParcel(Parcel in) {
5445 readFromParcelLocked(in);
5446 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005448 void readFromParcelLocked(Parcel in) {
5449 int magic = in.readInt();
5450 if (magic != MAGIC) {
5451 throw new ParcelFormatException("Bad magic number");
5452 }
5453
Dianne Hackbornae384452011-06-28 12:33:48 -07005454 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005456 mStartCount = in.readInt();
5457 mBatteryUptime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005458 mBatteryLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005459 mBatteryRealtime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005460 mBatteryLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005461 mScreenOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005462 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005463 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005464 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i,
5465 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005466 }
5467 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005468 mPhoneOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005469 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Wink Saville52840902011-02-18 12:40:47 -08005470 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005471 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
5472 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005473 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005474 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005475 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005476 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
5477 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005478 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005479 mWifiOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005480 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005481 mGlobalWifiRunning = false;
5482 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005483 mBluetoothOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005484 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005485 mUptime = in.readLong();
5486 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005487 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005488 mRealtime = in.readLong();
5489 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005490 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005491 mOnBattery = in.readInt() != 0;
5492 mOnBatteryInternal = false; // we are no longer really running.
5493 mTrackBatteryPastUptime = in.readLong();
5494 mTrackBatteryUptimeStart = in.readLong();
5495 mTrackBatteryPastRealtime = in.readLong();
5496 mTrackBatteryRealtimeStart = in.readLong();
5497 mUnpluggedBatteryUptime = in.readLong();
5498 mUnpluggedBatteryRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005499 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005500 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005501 mLowDischargeAmountSinceCharge = in.readInt();
5502 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005503 mDischargeAmountScreenOn = in.readInt();
5504 mDischargeAmountScreenOnSinceCharge = in.readInt();
5505 mDischargeAmountScreenOff = in.readInt();
5506 mDischargeAmountScreenOffSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005507 mLastWriteTime = in.readLong();
5508
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005509 mMobileDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005510 mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005511 mMobileDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005512 mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005513 mTotalDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005514 mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005515 mTotalDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005516 mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005517
5518 mRadioDataUptime = in.readLong();
5519 mRadioDataStart = -1;
5520
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005521 mBluetoothPingCount = in.readInt();
5522 mBluetoothPingStart = -1;
5523
Evan Millarc64edde2009-04-18 12:26:32 -07005524 mKernelWakelockStats.clear();
5525 int NKW = in.readInt();
5526 for (int ikw = 0; ikw < NKW; ikw++) {
5527 if (in.readInt() != 0) {
5528 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005529 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07005530 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
5531 mKernelWakelockStats.put(wakelockName, kwlt);
5532 }
5533 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005535 mPartialTimers.clear();
5536 mFullTimers.clear();
5537 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005538 mWifiRunningTimers.clear();
5539 mFullWifiLockTimers.clear();
5540 mScanWifiLockTimers.clear();
5541 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005542
Amith Yamasanie43530a2009-08-21 13:11:37 -07005543 sNumSpeedSteps = in.readInt();
5544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005545 int numUids = in.readInt();
5546 mUidStats.clear();
5547 for (int i = 0; i < numUids; i++) {
5548 int uid = in.readInt();
5549 Uid u = new Uid(uid);
5550 u.readFromParcelLocked(mUnpluggables, in);
5551 mUidStats.append(uid, u);
5552 }
5553 }
5554
5555 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005556 writeToParcelLocked(out, true, flags);
5557 }
5558
5559 public void writeToParcelWithoutUids(Parcel out, int flags) {
5560 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005561 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005562
5563 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005564 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005565 // Need to update with current kernel wake lock counts.
5566 updateKernelWakelocksLocked();
5567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005568 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
5569 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
5570 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
5571 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005573 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005574
Dianne Hackbornae384452011-06-28 12:33:48 -07005575 writeHistory(out, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005577 out.writeInt(mStartCount);
5578 out.writeLong(mBatteryUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005579 out.writeLong(mBatteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005580 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005581 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5582 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
5583 }
5584 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005585 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Wink Saville52840902011-02-18 12:40:47 -08005586 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005587 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
5588 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005589 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005590 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5591 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
5592 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005593 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005594 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005595 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005596 out.writeLong(mUptime);
5597 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005598 out.writeLong(mRealtime);
5599 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005600 out.writeInt(mOnBattery ? 1 : 0);
5601 out.writeLong(batteryUptime);
5602 out.writeLong(mTrackBatteryUptimeStart);
5603 out.writeLong(batteryRealtime);
5604 out.writeLong(mTrackBatteryRealtimeStart);
5605 out.writeLong(mUnpluggedBatteryUptime);
5606 out.writeLong(mUnpluggedBatteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005607 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005608 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005609 out.writeInt(mLowDischargeAmountSinceCharge);
5610 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005611 out.writeInt(mDischargeAmountScreenOn);
5612 out.writeInt(mDischargeAmountScreenOnSinceCharge);
5613 out.writeInt(mDischargeAmountScreenOff);
5614 out.writeInt(mDischargeAmountScreenOffSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005615 out.writeLong(mLastWriteTime);
5616
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005617 out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5618 out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED));
5619 out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5620 out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED));
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005621
5622 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005623 out.writeLong(getRadioDataUptime());
5624
5625 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005626
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005627 if (inclUids) {
5628 out.writeInt(mKernelWakelockStats.size());
5629 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5630 SamplingTimer kwlt = ent.getValue();
5631 if (kwlt != null) {
5632 out.writeInt(1);
5633 out.writeString(ent.getKey());
5634 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
5635 } else {
5636 out.writeInt(0);
5637 }
Evan Millarc64edde2009-04-18 12:26:32 -07005638 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005639 } else {
5640 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07005641 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005642
5643 out.writeInt(sNumSpeedSteps);
5644
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005645 if (inclUids) {
5646 int size = mUidStats.size();
5647 out.writeInt(size);
5648 for (int i = 0; i < size; i++) {
5649 out.writeInt(mUidStats.keyAt(i));
5650 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005651
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005652 uid.writeToParcelLocked(out, batteryRealtime);
5653 }
5654 } else {
5655 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005656 }
5657 }
5658
5659 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
5660 new Parcelable.Creator<BatteryStatsImpl>() {
5661 public BatteryStatsImpl createFromParcel(Parcel in) {
5662 return new BatteryStatsImpl(in);
5663 }
5664
5665 public BatteryStatsImpl[] newArray(int size) {
5666 return new BatteryStatsImpl[size];
5667 }
5668 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005669
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005670 public void prepareForDumpLocked() {
5671 // Need to retrieve current kernel wake lock stats before printing.
5672 updateKernelWakelocksLocked();
5673 }
5674
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005675 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005676 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005677 Printer pr = new PrintWriterPrinter(pw);
5678 pr.println("*** Screen timer:");
5679 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005680 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005681 pr.println("*** Screen brightness #" + i + ":");
5682 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005683 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005684 pr.println("*** Input event counter:");
5685 mInputEventCounter.logState(pr, " ");
5686 pr.println("*** Phone timer:");
5687 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08005688 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005689 pr.println("*** Signal strength #" + i + ":");
5690 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005691 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005692 pr.println("*** Signal scanning :");
5693 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005694 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005695 pr.println("*** Data connection type #" + i + ":");
5696 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005697 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005698 pr.println("*** Wifi timer:");
5699 mWifiOnTimer.logState(pr, " ");
5700 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005701 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005702 pr.println("*** Bluetooth timer:");
5703 mBluetoothOnTimer.logState(pr, " ");
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005704 pr.println("*** Mobile ifaces:");
5705 pr.println(mMobileIfaces.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005706 }
5707 super.dumpLocked(pw);
5708 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005709
5710 private NetworkStats mNetworkSummaryCache;
5711 private NetworkStats mNetworkDetailCache;
5712
5713 private NetworkStats getNetworkStatsSummary() {
5714 // NOTE: calls from BatteryStatsService already hold this lock
5715 synchronized (this) {
5716 if (mNetworkSummaryCache == null
5717 || mNetworkSummaryCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) {
Jeff Sharkey418d12d2011-12-13 15:38:03 -08005718 mNetworkSummaryCache = null;
5719
5720 if (SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) {
5721 try {
5722 mNetworkSummaryCache = mNetworkStatsFactory.readNetworkStatsSummary();
5723 } catch (IllegalStateException e) {
5724 Log.wtf(TAG, "problem reading network stats", e);
5725 }
5726 }
5727
5728 if (mNetworkSummaryCache == null) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005729 mNetworkSummaryCache = new NetworkStats(SystemClock.elapsedRealtime(), 0);
5730 }
5731 }
5732 return mNetworkSummaryCache;
5733 }
5734 }
5735
5736 private NetworkStats getNetworkStatsDetailGroupedByUid() {
5737 // NOTE: calls from BatteryStatsService already hold this lock
5738 synchronized (this) {
5739 if (mNetworkDetailCache == null
5740 || mNetworkDetailCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) {
Jeff Sharkey418d12d2011-12-13 15:38:03 -08005741 mNetworkDetailCache = null;
5742
5743 if (SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) {
5744 try {
5745 mNetworkDetailCache = mNetworkStatsFactory
5746 .readNetworkStatsDetail().groupedByUid();
5747 } catch (IllegalStateException e) {
5748 Log.wtf(TAG, "problem reading network stats", e);
5749 }
5750 }
5751
5752 if (mNetworkDetailCache == null) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005753 mNetworkDetailCache = new NetworkStats(SystemClock.elapsedRealtime(), 0);
5754 }
5755 }
5756 return mNetworkDetailCache;
5757 }
5758 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005759}