blob: 490cbe4c6e33d03d2e7710ef72ba0bbf7c0e8f83 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070019import com.android.internal.util.JournaledFile;
20
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070021import android.bluetooth.BluetoothHeadset;
Ken Shirriff1719a392009-12-07 15:57:35 -080022import android.net.TrafficStats;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070023import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.os.BatteryStats;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070025import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070026import android.os.Handler;
27import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.os.Parcel;
29import android.os.ParcelFormatException;
30import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070031import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.os.SystemClock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070033import android.os.WorkSource;
Amith Yamasanif37447b2009-10-08 18:28:01 -070034import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070035import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070036import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.util.Log;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070038import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070040import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.util.SparseArray;
42
Amith Yamasani3718aaa2009-06-09 06:32:35 -070043import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import java.io.File;
45import java.io.FileInputStream;
46import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070047import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070049import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import java.util.ArrayList;
51import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070052import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070054import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070055import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056
57/**
58 * All information we are collecting about things that can happen that impact
59 * battery life. All times are represented in microseconds except where indicated
60 * otherwise.
61 */
62public final class BatteryStatsImpl extends BatteryStats {
63 private static final String TAG = "BatteryStatsImpl";
64 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070065 private static final boolean DEBUG_HISTORY = false;
66
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
68 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
69
70 // Current on-disk Parcel version
Dianne Hackborn287952c2010-09-22 22:34:31 -070071 private static final int VERSION = 52;
Amith Yamasanie43530a2009-08-21 13:11:37 -070072
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070073 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070074 private static final int MAX_HISTORY_ITEMS = 2000;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070075
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070076 // No, really, THIS is the maximum number of items we will record in the history.
77 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
78
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080079 // The maximum number of names wakelocks we will keep track of
80 // per uid; once the limit is reached, we batch the remaining wakelocks
81 // in to one common name.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070082 private static final int MAX_WAKELOCKS_PER_UID = 30;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080083
84 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
85
Amith Yamasanie43530a2009-08-21 13:11:37 -070086 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070088 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089
Dianne Hackborn0d903a82010-09-07 23:51:03 -070090 static final int MSG_UPDATE_WAKELOCKS = 1;
91 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -070092 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070093
94 public interface BatteryCallback {
95 public void batteryNeedsCpuUpdate();
96 public void batteryPowerChanged(boolean onBattery);
97 }
98
99 final class MyHandler extends Handler {
100 @Override
101 public void handleMessage(Message msg) {
102 BatteryCallback cb = mCallback;
103 switch (msg.what) {
104 case MSG_UPDATE_WAKELOCKS:
105 if (cb != null) {
106 cb.batteryNeedsCpuUpdate();
107 }
108 break;
109 case MSG_REPORT_POWER_CHANGE:
110 if (cb != null) {
111 cb.batteryPowerChanged(msg.arg1 != 0);
112 }
113 break;
114 }
115 }
116 }
117
118 private final MyHandler mHandler;
119
120 private BatteryCallback mCallback;
121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 /**
123 * The statistics we have collected organized by uids.
124 */
125 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
126 new SparseArray<BatteryStatsImpl.Uid>();
127
128 // A set of pools of currently active timers. When a timer is queried, we will divide the
129 // elapsed time by the number of active timers to arrive at that timer's share of the time.
130 // In order to do this, we must refresh each timer whenever the number of active timers
131 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700132 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
133 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
134 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
135 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
136 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700137 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
138 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
139 final ArrayList<StopwatchTimer> mScanWifiLockTimers = new ArrayList<StopwatchTimer>();
140 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700142 // Last partial timers we use for distributing CPU usage.
143 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 // These are the objects that will want to do something when the device
146 // is unplugged from power.
147 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
148
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700149 boolean mShuttingDown;
150
151 long mHistoryBaseTime;
152 boolean mHaveBatteryLevel = false;
153 boolean mRecordingHistory = true;
154 int mNumHistoryItems;
155 HistoryItem mHistory;
156 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700157 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700158 HistoryItem mHistoryCache;
159 final HistoryItem mHistoryCur = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 int mStartCount;
162
163 long mBatteryUptime;
164 long mBatteryLastUptime;
165 long mBatteryRealtime;
166 long mBatteryLastRealtime;
167
168 long mUptime;
169 long mUptimeStart;
170 long mLastUptime;
171 long mRealtime;
172 long mRealtimeStart;
173 long mLastRealtime;
174
175 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700176 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700177
Dianne Hackborn617f8772009-03-31 15:04:46 -0700178 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700179 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Dianne Hackborn617f8772009-03-31 15:04:46 -0700180
181 Counter mInputEventCounter;
182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700184 StopwatchTimer mPhoneOnTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700186 boolean mAudioOn;
187 StopwatchTimer mAudioOnTimer;
188
189 boolean mVideoOn;
190 StopwatchTimer mVideoOnTimer;
191
Dianne Hackborn627bba72009-03-24 22:32:56 -0700192 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800193 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700194 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
195 new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700196
197 StopwatchTimer mPhoneSignalScanningTimer;
198
Dianne Hackborn627bba72009-03-24 22:32:56 -0700199 int mPhoneDataConnectionType = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700200 final StopwatchTimer[] mPhoneDataConnectionsTimer =
201 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700202
The Android Open Source Project10592532009-03-18 17:39:46 -0700203 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700204 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700205 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700206
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700207 boolean mGlobalWifiRunning;
208 StopwatchTimer mGlobalWifiRunningTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -0700209
210 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700211 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700212
213 /** Bluetooth headset object */
214 BluetoothHeadset mBtHeadset;
215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 /**
217 * These provide time bases that discount the time the device is plugged
218 * in to power.
219 */
220 boolean mOnBattery;
221 boolean mOnBatteryInternal;
222 long mTrackBatteryPastUptime;
223 long mTrackBatteryUptimeStart;
224 long mTrackBatteryPastRealtime;
225 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 long mUnpluggedBatteryUptime;
228 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700229
The Android Open Source Project10592532009-03-18 17:39:46 -0700230 /*
231 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
232 */
Evan Millar633a1742009-04-02 16:36:33 -0700233 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700234 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700235 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700236 int mLowDischargeAmountSinceCharge;
237 int mHighDischargeAmountSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700240
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700241 // Mobile data transferred while on battery
242 private long[] mMobileDataTx = new long[4];
243 private long[] mMobileDataRx = new long[4];
244 private long[] mTotalDataTx = new long[4];
245 private long[] mTotalDataRx = new long[4];
246
247 private long mRadioDataUptime;
248 private long mRadioDataStart;
249
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700250 private int mBluetoothPingCount;
251 private int mBluetoothPingStart = -1;
252
Amith Yamasanif37447b2009-10-08 18:28:01 -0700253 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800254 private int mPhoneServiceStateRaw = -1;
255 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700256
Evan Millarc64edde2009-04-18 12:26:32 -0700257 /*
258 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
259 */
260 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
261 new HashMap<String, SamplingTimer>();
262
263 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
264 return mKernelWakelockStats;
265 }
266
267 private static int sKernelWakelockUpdateVersion = 0;
268
269 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
270 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
271 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
272 Process.PROC_TAB_TERM,
273 Process.PROC_TAB_TERM,
274 Process.PROC_TAB_TERM,
275 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
276 };
277
278 private final String[] mProcWakelocksName = new String[3];
279 private final long[] mProcWakelocksData = new long[3];
280
281 /*
282 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
283 * to mKernelWakelockStats.
284 */
285 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
286 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700288 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 // For debugging
291 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700292 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700293 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 }
295
296 public static interface Unpluggable {
297 void unplug(long batteryUptime, long batteryRealtime);
298 void plug(long batteryUptime, long batteryRealtime);
299 }
300
301 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700302 * State for keeping track of counting information.
303 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700304 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700305 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700306 final ArrayList<Unpluggable> mUnpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700307 int mLoadedCount;
308 int mLastCount;
309 int mUnpluggedCount;
310 int mPluggedCount;
311
312 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700313 mUnpluggables = unpluggables;
Christopher Tate4cee7252010-03-19 14:50:40 -0700314 mPluggedCount = in.readInt();
315 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700316 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700317 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700318 mUnpluggedCount = in.readInt();
319 unpluggables.add(this);
320 }
321
322 Counter(ArrayList<Unpluggable> unpluggables) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700323 mUnpluggables = unpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700324 unpluggables.add(this);
325 }
326
327 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700328 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700329 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700330 out.writeInt(mUnpluggedCount);
331 }
332
333 public void unplug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700334 mUnpluggedCount = mPluggedCount;
335 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700336 }
337
338 public void plug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700339 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700340 }
341
342 /**
343 * Writes a possibly null Counter to a Parcel.
344 *
345 * @param out the Parcel to be written to.
346 * @param counter a Counter, or null.
347 */
348 public static void writeCounterToParcel(Parcel out, Counter counter) {
349 if (counter == null) {
350 out.writeInt(0); // indicates null
351 return;
352 }
353 out.writeInt(1); // indicates non-null
354
355 counter.writeToParcel(out);
356 }
357
358 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700359 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700360 int val;
361 if (which == STATS_LAST) {
362 val = mLastCount;
363 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700364 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700365 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700366 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700367 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700368 val -= mLoadedCount;
369 }
370 }
371
372 return val;
373 }
374
375 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700376 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700377 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
378 + " mUnpluggedCount=" + mUnpluggedCount
379 + " mPluggedCount=" + mPluggedCount);
380 }
381
Christopher Tate4cee7252010-03-19 14:50:40 -0700382 void stepAtomic() {
383 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700384 }
385
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700386 /**
387 * Clear state of this counter.
388 */
389 void reset(boolean detachIfReset) {
390 mCount.set(0);
391 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
392 if (detachIfReset) {
393 detach();
394 }
395 }
396
397 void detach() {
398 mUnpluggables.remove(this);
399 }
400
Dianne Hackborn617f8772009-03-31 15:04:46 -0700401 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700402 int count = mCount.get();
403 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700404 }
405
406 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700407 mLoadedCount = in.readInt();
408 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700409 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700410 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700411 }
412 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700413
414 public static class SamplingCounter extends Counter {
415
416 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
417 super(unpluggables, in);
418 }
419
420 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
421 super(unpluggables);
422 }
423
Christopher Tate4cee7252010-03-19 14:50:40 -0700424 public void addCountAtomic(long count) {
425 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700426 }
427 }
428
Dianne Hackborn617f8772009-03-31 15:04:46 -0700429 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 * State for keeping track of timing information.
431 */
Evan Millarc64edde2009-04-18 12:26:32 -0700432 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 final int mType;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700434 final ArrayList<Unpluggable> mUnpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435
436 int mCount;
437 int mLoadedCount;
438 int mLastCount;
439 int mUnpluggedCount;
440
441 // Times are in microseconds for better accuracy when dividing by the
442 // lock count, and are in "battery realtime" units.
443
444 /**
445 * The total time we have accumulated since the start of the original
446 * boot, to the last time something interesting happened in the
447 * current run.
448 */
449 long mTotalTime;
450
451 /**
452 * The total time we loaded for the previous runs. Subtract this from
453 * mTotalTime to find the time for the current run of the system.
454 */
455 long mLoadedTime;
456
457 /**
458 * The run time of the last run of the system, as loaded from the
459 * saved data.
460 */
461 long mLastTime;
462
463 /**
464 * The value of mTotalTime when unplug() was last called. Subtract
465 * this from mTotalTime to find the time since the last unplug from
466 * power.
467 */
468 long mUnpluggedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700470 /**
471 * Constructs from a parcel.
472 * @param type
473 * @param unpluggables
474 * @param powerType
475 * @param in
476 */
Evan Millarc64edde2009-04-18 12:26:32 -0700477 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700479 mUnpluggables = unpluggables;
Evan Millarc64edde2009-04-18 12:26:32 -0700480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 mCount = in.readInt();
482 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700483 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 mUnpluggedCount = in.readInt();
485 mTotalTime = in.readLong();
486 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700487 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 mUnpluggedTime = in.readLong();
489 unpluggables.add(this);
490 }
491
Evan Millarc64edde2009-04-18 12:26:32 -0700492 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700494 mUnpluggables = unpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 unpluggables.add(this);
496 }
Evan Millarc64edde2009-04-18 12:26:32 -0700497
498 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
499
500 protected abstract int computeCurrentCountLocked();
501
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700502 /**
503 * Clear state of this timer. Returns true if the timer is inactive
504 * so can be completely dropped.
505 */
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700506 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700507 mTotalTime = mLoadedTime = mLastTime = 0;
508 mCount = mLoadedCount = mLastCount = 0;
509 if (detachIfReset) {
510 detach();
511 }
512 return true;
513 }
514
515 void detach() {
516 mUnpluggables.remove(this);
517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518
519 public void writeToParcel(Parcel out, long batteryRealtime) {
520 out.writeInt(mCount);
521 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522 out.writeInt(mUnpluggedCount);
523 out.writeLong(computeRunTimeLocked(batteryRealtime));
524 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 out.writeLong(mUnpluggedTime);
526 }
527
528 public void unplug(long batteryUptime, long batteryRealtime) {
529 if (DEBUG && mType < 0) {
530 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
531 + " old mUnpluggedTime=" + mUnpluggedTime
532 + " old mUnpluggedCount=" + mUnpluggedCount);
533 }
534 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
535 mUnpluggedCount = mCount;
536 if (DEBUG && mType < 0) {
537 Log.v(TAG, "unplug #" + mType
538 + ": new mUnpluggedTime=" + mUnpluggedTime
539 + " new mUnpluggedCount=" + mUnpluggedCount);
540 }
541 }
542
543 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700544 if (DEBUG && mType < 0) {
545 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
546 + " old mTotalTime=" + mTotalTime);
547 }
548 mTotalTime = computeRunTimeLocked(batteryRealtime);
549 mCount = computeCurrentCountLocked();
550 if (DEBUG && mType < 0) {
551 Log.v(TAG, "plug #" + mType
552 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 }
554 }
555
556 /**
557 * Writes a possibly null Timer to a Parcel.
558 *
559 * @param out the Parcel to be written to.
560 * @param timer a Timer, or null.
561 */
562 public static void writeTimerToParcel(Parcel out, Timer timer,
563 long batteryRealtime) {
564 if (timer == null) {
565 out.writeInt(0); // indicates null
566 return;
567 }
568 out.writeInt(1); // indicates non-null
569
570 timer.writeToParcel(out, batteryRealtime);
571 }
572
573 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700574 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 long val;
576 if (which == STATS_LAST) {
577 val = mLastTime;
578 } else {
579 val = computeRunTimeLocked(batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700580 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 val -= mUnpluggedTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700582 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 val -= mLoadedTime;
584 }
585 }
586
587 return val;
588 }
589
590 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700591 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 int val;
593 if (which == STATS_LAST) {
594 val = mLastCount;
595 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700596 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700597 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700599 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 val -= mLoadedCount;
601 }
602 }
603
604 return val;
605 }
606
Dianne Hackborn627bba72009-03-24 22:32:56 -0700607 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700608 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
610 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700611 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700613 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700615 }
616
617
618 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
619 long runTime = computeRunTimeLocked(batteryRealtime);
620 // Divide by 1000 for backwards compatibility
621 out.writeLong((runTime + 500) / 1000);
Evan Millarc64edde2009-04-18 12:26:32 -0700622 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -0700623 }
624
625 void readSummaryFromParcelLocked(Parcel in) {
626 // Multiply by 1000 for backwards compatibility
627 mTotalTime = mLoadedTime = in.readLong() * 1000;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700628 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700629 mUnpluggedTime = mTotalTime;
630 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700631 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700632 mUnpluggedCount = mCount;
633 }
634 }
635
636 public static final class SamplingTimer extends Timer {
637
638 /**
639 * The most recent reported count from /proc/wakelocks.
640 */
641 int mCurrentReportedCount;
642
643 /**
644 * The reported count from /proc/wakelocks when unplug() was last
645 * called.
646 */
647 int mUnpluggedReportedCount;
648
649 /**
650 * The most recent reported total_time from /proc/wakelocks.
651 */
652 long mCurrentReportedTotalTime;
653
654
655 /**
656 * The reported total_time from /proc/wakelocks when unplug() was last
657 * called.
658 */
659 long mUnpluggedReportedTotalTime;
660
661 /**
662 * Whether we are currently in a discharge cycle.
663 */
664 boolean mInDischarge;
665
666 /**
667 * Whether we are currently recording reported values.
668 */
669 boolean mTrackingReportedValues;
670
671 /*
672 * A sequnce counter, incremented once for each update of the stats.
673 */
674 int mUpdateVersion;
675
676 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
677 super(0, unpluggables, in);
678 mCurrentReportedCount = in.readInt();
679 mUnpluggedReportedCount = in.readInt();
680 mCurrentReportedTotalTime = in.readLong();
681 mUnpluggedReportedTotalTime = in.readLong();
682 mTrackingReportedValues = in.readInt() == 1;
683 mInDischarge = inDischarge;
684 }
685
686 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
687 boolean trackReportedValues) {
688 super(0, unpluggables);
689 mTrackingReportedValues = trackReportedValues;
690 mInDischarge = inDischarge;
691 }
692
693 public void setStale() {
694 mTrackingReportedValues = false;
695 mUnpluggedReportedTotalTime = 0;
696 mUnpluggedReportedCount = 0;
697 }
698
699 public void setUpdateVersion(int version) {
700 mUpdateVersion = version;
701 }
702
703 public int getUpdateVersion() {
704 return mUpdateVersion;
705 }
706
707 public void updateCurrentReportedCount(int count) {
708 if (mInDischarge && mUnpluggedReportedCount == 0) {
709 // Updating the reported value for the first time.
710 mUnpluggedReportedCount = count;
711 // If we are receiving an update update mTrackingReportedValues;
712 mTrackingReportedValues = true;
713 }
714 mCurrentReportedCount = count;
715 }
716
717 public void updateCurrentReportedTotalTime(long totalTime) {
718 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
719 // Updating the reported value for the first time.
720 mUnpluggedReportedTotalTime = totalTime;
721 // If we are receiving an update update mTrackingReportedValues;
722 mTrackingReportedValues = true;
723 }
724 mCurrentReportedTotalTime = totalTime;
725 }
726
727 public void unplug(long batteryUptime, long batteryRealtime) {
728 super.unplug(batteryUptime, batteryRealtime);
729 if (mTrackingReportedValues) {
730 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
731 mUnpluggedReportedCount = mCurrentReportedCount;
732 }
733 mInDischarge = true;
734 }
735
736 public void plug(long batteryUptime, long batteryRealtime) {
737 super.plug(batteryUptime, batteryRealtime);
738 mInDischarge = false;
739 }
740
741 public void logState(Printer pw, String prefix) {
742 super.logState(pw, prefix);
743 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
744 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
745 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
746 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
747 }
748
749 protected long computeRunTimeLocked(long curBatteryRealtime) {
750 return mTotalTime + (mInDischarge && mTrackingReportedValues
751 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
752 }
753
754 protected int computeCurrentCountLocked() {
755 return mCount + (mInDischarge && mTrackingReportedValues
756 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
757 }
758
759 public void writeToParcel(Parcel out, long batteryRealtime) {
760 super.writeToParcel(out, batteryRealtime);
761 out.writeInt(mCurrentReportedCount);
762 out.writeInt(mUnpluggedReportedCount);
763 out.writeLong(mCurrentReportedTotalTime);
764 out.writeLong(mUnpluggedReportedTotalTime);
765 out.writeInt(mTrackingReportedValues ? 1 : 0);
766 }
767
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700768 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
769 super.reset(stats, detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700770 setStale();
771 return true;
772 }
773
Evan Millarc64edde2009-04-18 12:26:32 -0700774 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
775 super.writeSummaryFromParcelLocked(out, batteryRealtime);
776 out.writeLong(mCurrentReportedTotalTime);
777 out.writeInt(mCurrentReportedCount);
778 out.writeInt(mTrackingReportedValues ? 1 : 0);
779 }
780
781 void readSummaryFromParcelLocked(Parcel in) {
782 super.readSummaryFromParcelLocked(in);
783 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
784 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
785 mTrackingReportedValues = in.readInt() == 1;
786 }
787 }
788
789 /**
790 * State for keeping track of timing information.
791 */
792 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700793 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -0700794 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700795
Evan Millarc64edde2009-04-18 12:26:32 -0700796 int mNesting;
797
Evan Millarc64edde2009-04-18 12:26:32 -0700798 /**
799 * The last time at which we updated the timer. If mNesting is > 0,
800 * subtract this from the current battery time to find the amount of
801 * time we have been running since we last computed an update.
802 */
803 long mUpdateTime;
804
805 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700806 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -0700807 * was actually held for an interesting duration.
808 */
809 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700810
Amith Yamasanif37447b2009-10-08 18:28:01 -0700811 long mTimeout;
812
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700813 /**
814 * For partial wake locks, keep track of whether we are in the list
815 * to consume CPU cycles.
816 */
817 boolean mInList;
818
819 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700820 ArrayList<Unpluggable> unpluggables, Parcel in) {
821 super(type, unpluggables, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700822 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700823 mTimerPool = timerPool;
824 mUpdateTime = in.readLong();
825 }
826
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700827 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700828 ArrayList<Unpluggable> unpluggables) {
829 super(type, unpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700830 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700831 mTimerPool = timerPool;
832 }
833
Amith Yamasanif37447b2009-10-08 18:28:01 -0700834 void setTimeout(long timeout) {
835 mTimeout = timeout;
836 }
837
Evan Millarc64edde2009-04-18 12:26:32 -0700838 public void writeToParcel(Parcel out, long batteryRealtime) {
839 super.writeToParcel(out, batteryRealtime);
840 out.writeLong(mUpdateTime);
841 }
842
843 public void plug(long batteryUptime, long batteryRealtime) {
844 if (mNesting > 0) {
845 if (DEBUG && mType < 0) {
846 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
847 }
848 super.plug(batteryUptime, batteryRealtime);
849 mUpdateTime = batteryRealtime;
850 if (DEBUG && mType < 0) {
851 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
852 }
853 }
854 }
855
856 public void logState(Printer pw, String prefix) {
857 super.logState(pw, prefix);
858 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 + " mAcquireTime=" + mAcquireTime);
860 }
861
862 void startRunningLocked(BatteryStatsImpl stats) {
863 if (mNesting++ == 0) {
864 mUpdateTime = stats.getBatteryRealtimeLocked(
865 SystemClock.elapsedRealtime() * 1000);
866 if (mTimerPool != null) {
867 // Accumulate time to all currently active timers before adding
868 // this new one to the pool.
869 refreshTimersLocked(stats, mTimerPool);
870 // Add this timer to the active pool
871 mTimerPool.add(this);
872 }
873 // Increment the count
874 mCount++;
875 mAcquireTime = mTotalTime;
876 if (DEBUG && mType < 0) {
877 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
878 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
879 + " mAcquireTime=" + mAcquireTime);
880 }
881 }
882 }
883
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700884 boolean isRunningLocked() {
885 return mNesting > 0;
886 }
887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888 void stopRunningLocked(BatteryStatsImpl stats) {
889 // Ignore attempt to stop a timer that isn't running
890 if (mNesting == 0) {
891 return;
892 }
893 if (--mNesting == 0) {
894 if (mTimerPool != null) {
895 // Accumulate time to all active counters, scaled by the total
896 // active in the pool, before taking this one out of the pool.
897 refreshTimersLocked(stats, mTimerPool);
898 // Remove this timer from the active pool
899 mTimerPool.remove(this);
900 } else {
901 final long realtime = SystemClock.elapsedRealtime() * 1000;
902 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
903 mNesting = 1;
904 mTotalTime = computeRunTimeLocked(batteryRealtime);
905 mNesting = 0;
906 }
907
908 if (DEBUG && mType < 0) {
909 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
910 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
911 + " mAcquireTime=" + mAcquireTime);
912 }
913
914 if (mTotalTime == mAcquireTime) {
915 // If there was no change in the time, then discard this
916 // count. A somewhat cheezy strategy, but hey.
917 mCount--;
918 }
919 }
920 }
921
922 // Update the total time for all other running Timers with the same type as this Timer
923 // due to a change in timer count
924 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700925 final ArrayList<StopwatchTimer> pool) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 final long realtime = SystemClock.elapsedRealtime() * 1000;
927 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
928 final int N = pool.size();
929 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700930 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 long heldTime = batteryRealtime - t.mUpdateTime;
932 if (heldTime > 0) {
933 t.mTotalTime += heldTime / N;
934 }
935 t.mUpdateTime = batteryRealtime;
936 }
937 }
938
Evan Millarc64edde2009-04-18 12:26:32 -0700939 @Override
940 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700941 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
942 curBatteryRealtime = mUpdateTime + mTimeout;
943 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 return mTotalTime + (mNesting > 0
945 ? (curBatteryRealtime - mUpdateTime)
946 / (mTimerPool != null ? mTimerPool.size() : 1)
947 : 0);
948 }
949
Evan Millarc64edde2009-04-18 12:26:32 -0700950 @Override
951 protected int computeCurrentCountLocked() {
952 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 }
954
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700955 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700956 boolean canDetach = mNesting <= 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700957 super.reset(stats, canDetach && detachIfReset);
958 if (mNesting > 0) {
959 mUpdateTime = stats.getBatteryRealtimeLocked(
960 SystemClock.elapsedRealtime() * 1000);
961 }
962 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700963 return canDetach;
964 }
965
966 void detach() {
967 super.detach();
968 if (mTimerPool != null) {
969 mTimerPool.remove(this);
970 }
971 }
972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -0700974 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 mNesting = 0;
976 }
977 }
978
Evan Millarc64edde2009-04-18 12:26:32 -0700979 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
980
981 byte[] buffer = new byte[4096];
982 int len;
983
984 try {
985 FileInputStream is = new FileInputStream("/proc/wakelocks");
986 len = is.read(buffer);
987 is.close();
988
989 if (len > 0) {
990 int i;
991 for (i=0; i<len; i++) {
992 if (buffer[i] == '\0') {
993 len = i;
994 break;
995 }
996 }
997 }
998 } catch (java.io.FileNotFoundException e) {
999 return null;
1000 } catch (java.io.IOException e) {
1001 return null;
1002 }
1003
1004 return parseProcWakelocks(buffer, len);
1005 }
1006
1007 private final Map<String, KernelWakelockStats> parseProcWakelocks(
1008 byte[] wlBuffer, int len) {
1009 String name;
1010 int count;
1011 long totalTime;
1012 int startIndex, endIndex;
1013 int numUpdatedWlNames = 0;
1014
1015 // Advance past the first line.
1016 int i;
1017 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1018 startIndex = endIndex = i + 1;
1019
1020 synchronized(this) {
1021 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
1022
1023 sKernelWakelockUpdateVersion++;
1024 while (endIndex < len) {
1025 for (endIndex=startIndex;
1026 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
1027 endIndex++);
Amith Yamasanie5795612010-04-05 12:43:44 -07001028 // Don't go over the end of the buffer
1029 if (endIndex < len) {
1030 endIndex++; // endIndex is an exclusive upper bound.
1031 }
Evan Millarc64edde2009-04-18 12:26:32 -07001032
1033 String[] nameStringArray = mProcWakelocksName;
1034 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001035 // Stomp out any bad characters since this is from a circular buffer
1036 // A corruption is seen sometimes that results in the vm crashing
1037 // This should prevent crashes and the line will probably fail to parse
1038 for (int j = startIndex; j < endIndex; j++) {
1039 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1040 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001041 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
1042 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001043
Evan Millarc64edde2009-04-18 12:26:32 -07001044 name = nameStringArray[0];
1045 count = (int) wlData[1];
1046 // convert nanoseconds to microseconds with rounding.
1047 totalTime = (wlData[2] + 500) / 1000;
1048
Amith Yamasani53b707b2009-09-30 11:05:30 -07001049 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001050 if (!m.containsKey(name)) {
1051 m.put(name, new KernelWakelockStats(count, totalTime,
1052 sKernelWakelockUpdateVersion));
1053 numUpdatedWlNames++;
1054 } else {
1055 KernelWakelockStats kwlStats = m.get(name);
1056 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1057 kwlStats.mCount += count;
1058 kwlStats.mTotalTime += totalTime;
1059 } else {
1060 kwlStats.mCount = count;
1061 kwlStats.mTotalTime = totalTime;
1062 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1063 numUpdatedWlNames++;
1064 }
1065 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001066 }
Evan Millarc64edde2009-04-18 12:26:32 -07001067 startIndex = endIndex;
1068 }
1069
1070 if (m.size() != numUpdatedWlNames) {
1071 // Don't report old data.
1072 Iterator<KernelWakelockStats> itr = m.values().iterator();
1073 while (itr.hasNext()) {
1074 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1075 itr.remove();
1076 }
1077 }
1078 }
1079 return m;
1080 }
1081 }
1082
1083 private class KernelWakelockStats {
1084 public int mCount;
1085 public long mTotalTime;
1086 public int mVersion;
1087
1088 KernelWakelockStats(int count, long totalTime, int version) {
1089 mCount = count;
1090 mTotalTime = totalTime;
1091 mVersion = version;
1092 }
1093 }
1094
1095 /*
1096 * Get the KernelWakelockTimer associated with name, and create a new one if one
1097 * doesn't already exist.
1098 */
1099 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1100 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1101 if (kwlt == null) {
1102 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
1103 true /* track reported values */);
1104 mKernelWakelockStats.put(name, kwlt);
1105 }
1106 return kwlt;
1107 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001108
1109 private void doDataPlug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001110 dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED];
1111 dataTransfer[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001112 }
1113
1114 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001115 dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001116 }
1117
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001118 /**
1119 * Radio uptime in microseconds when transferring data. This value is very approximate.
1120 * @return
1121 */
1122 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001123 try {
1124 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
1125 if (!awakeTimeFile.exists()) return 0;
1126 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
1127 String line = br.readLine();
1128 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001129 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001130 } catch (NumberFormatException nfe) {
1131 // Nothing
1132 } catch (IOException ioe) {
1133 // Nothing
1134 }
1135 return 0;
1136 }
1137
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001138 /**
1139 * @deprecated use getRadioDataUptime
1140 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001141 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001142 return getRadioDataUptime() / 1000;
1143 }
1144
1145 /**
1146 * Returns the duration that the cell radio was up for data transfers.
1147 */
1148 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001149 if (mRadioDataStart == -1) {
1150 return mRadioDataUptime;
1151 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001152 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001153 }
1154 }
1155
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001156 private int getCurrentBluetoothPingCount() {
1157 if (mBtHeadset != null) {
1158 return mBtHeadset.getBatteryUsageHint();
1159 }
1160 return -1;
1161 }
1162
1163 public int getBluetoothPingCount() {
1164 if (mBluetoothPingStart == -1) {
1165 return mBluetoothPingCount;
1166 } else if (mBtHeadset != null) {
1167 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1168 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001169 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001170 }
1171
1172 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001173 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1174 mBluetoothPingStart = getCurrentBluetoothPingCount();
1175 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001176 mBtHeadset = headset;
1177 }
1178
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001179 int mChangedStates = 0;
1180
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001181 void addHistoryRecordLocked(long curTime) {
1182 if (!mHaveBatteryLevel || !mRecordingHistory) {
1183 return;
1184 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001185
1186 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001187 // and no states have since the last recorded entry changed and
1188 // are now resetting back to their original value, then just collapse
1189 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001190 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001191 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000)
1192 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001193 // If the current is the same as the one before, then we no
1194 // longer need the entry.
1195 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
1196 && mHistoryLastEnd.same(mHistoryCur)) {
1197 mHistoryLastEnd.next = null;
1198 mHistoryEnd.next = mHistoryCache;
1199 mHistoryCache = mHistoryEnd;
1200 mHistoryEnd = mHistoryLastEnd;
1201 mHistoryLastEnd = null;
1202 } else {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001203 mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001204 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
1205 }
1206 return;
1207 }
1208
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001209 mChangedStates = 0;
1210
1211 if (mNumHistoryItems == MAX_HISTORY_ITEMS
1212 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001213 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
1214 }
1215
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001216 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
1217 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001218 // record changes to the battery level and the most interesting states.
1219 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001220 // record changes to the battery level.
1221 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001222 == mHistoryCur.batteryLevel &&
1223 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
1224 || ((mHistoryEnd.states^mHistoryCur.states)
1225 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001226 return;
1227 }
1228 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001229
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001230 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
1231 }
1232
1233 void addHistoryRecordLocked(long curTime, byte cmd) {
1234 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001235 if (rec != null) {
1236 mHistoryCache = rec.next;
1237 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001238 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001239 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001240 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
1241
1242 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001243 }
1244
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001245 void addHistoryRecordLocked(HistoryItem rec) {
1246 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001247 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001248 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001249 if (mHistoryEnd != null) {
1250 mHistoryEnd.next = rec;
1251 mHistoryEnd = rec;
1252 } else {
1253 mHistory = mHistoryEnd = rec;
1254 }
1255 }
1256
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001257 void clearHistoryLocked() {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001258 if (mHistory != null) {
1259 mHistoryEnd.next = mHistoryCache;
1260 mHistoryCache = mHistory;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001261 mHistory = mHistoryLastEnd = mHistoryEnd = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001262 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001263 mNumHistoryItems = 0;
1264 mHistoryBaseTime = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001265 }
1266
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001267 public void doUnplugLocked(long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1269 Uid u = mUidStats.valueAt(iu);
Ken Shirriff1719a392009-12-07 15:57:35 -08001270 u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid);
1271 u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1273 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1274 }
1275 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1276 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
1277 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001278 // Track total mobile data
Ken Shirriff1719a392009-12-07 15:57:35 -08001279 doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1280 doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1281 doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1282 doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001283 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001284 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001285 mRadioDataUptime = 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001286 // Track bt headset ping count
1287 mBluetoothPingStart = getCurrentBluetoothPingCount();
1288 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001290
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001291 public void doPlugLocked(long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1293 Uid u = mUidStats.valueAt(iu);
1294 if (u.mStartedTcpBytesReceived >= 0) {
1295 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1296 u.mStartedTcpBytesReceived = -1;
1297 }
1298 if (u.mStartedTcpBytesSent >= 0) {
1299 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1300 u.mStartedTcpBytesSent = -1;
1301 }
1302 }
1303 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1304 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
1305 }
Ken Shirriff1719a392009-12-07 15:57:35 -08001306 doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1307 doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1308 doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1309 doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001310 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001311 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001312 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001313
1314 // Track bt headset ping count
1315 mBluetoothPingCount = getBluetoothPingCount();
1316 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001318
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001319 int mWakeLockNesting;
1320
1321 public void noteStartWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001322 if (type == WAKE_TYPE_PARTIAL) {
1323 // Only care about partial wake locks, since full wake locks
1324 // will be canceled when the user puts the screen to sleep.
1325 if (mWakeLockNesting == 0) {
1326 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
1327 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
1328 + Integer.toHexString(mHistoryCur.states));
1329 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1330 }
1331 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001332 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001333 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001334 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1335 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1336 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1337 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001338 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
1339 }
1340 }
1341
1342 public void noteStopWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001343 if (type == WAKE_TYPE_PARTIAL) {
1344 mWakeLockNesting--;
1345 if (mWakeLockNesting == 0) {
1346 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
1347 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
1348 + Integer.toHexString(mHistoryCur.states));
1349 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1350 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001351 }
1352 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001353 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1354 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1355 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1356 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001357 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
1358 }
1359 }
1360
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001361 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1362 int N = ws.size();
1363 for (int i=0; i<N; i++) {
1364 noteStartWakeLocked(ws.get(i), pid, name, type);
1365 }
1366 }
1367
1368 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1369 int N = ws.size();
1370 for (int i=0; i<N; i++) {
1371 noteStopWakeLocked(ws.get(i), pid, name, type);
1372 }
1373 }
1374
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001375 public int startAddingCpuLocked() {
1376 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
1377
1378 if (mScreenOn) {
1379 return 0;
1380 }
1381
1382 final int N = mPartialTimers.size();
1383 if (N == 0) {
1384 mLastPartialTimers.clear();
1385 return 0;
1386 }
1387
1388 // How many timers should consume CPU? Only want to include ones
1389 // that have already been in the list.
1390 for (int i=0; i<N; i++) {
1391 StopwatchTimer st = mPartialTimers.get(i);
1392 if (st.mInList) {
1393 Uid uid = st.mUid;
1394 // We don't include the system UID, because it so often
1395 // holds wake locks at one request or another of an app.
1396 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1397 return 50;
1398 }
1399 }
1400 }
1401
1402 return 0;
1403 }
1404
1405 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
1406 final int N = mPartialTimers.size();
1407 if (perc != 0) {
1408 int num = 0;
1409 for (int i=0; i<N; i++) {
1410 StopwatchTimer st = mPartialTimers.get(i);
1411 if (st.mInList) {
1412 Uid uid = st.mUid;
1413 // We don't include the system UID, because it so often
1414 // holds wake locks at one request or another of an app.
1415 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1416 num++;
1417 }
1418 }
1419 }
1420 if (num != 0) {
1421 for (int i=0; i<N; i++) {
1422 StopwatchTimer st = mPartialTimers.get(i);
1423 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001424 Uid uid = st.mUid;
1425 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07001426 int myUTime = utime/num;
1427 int mySTime = stime/num;
1428 utime -= myUTime;
1429 stime -= mySTime;
1430 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001431 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
1432 proc.addCpuTimeLocked(myUTime, mySTime);
1433 proc.addSpeedStepTimes(cpuSpeedTimes);
1434 }
1435 }
1436 }
1437 }
1438
1439 // Just in case, collect any lost CPU time.
1440 if (utime != 0 || stime != 0) {
1441 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
1442 if (uid != null) {
1443 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
1444 proc.addCpuTimeLocked(utime, stime);
1445 proc.addSpeedStepTimes(cpuSpeedTimes);
1446 }
1447 }
1448 }
1449
1450 final int NL = mLastPartialTimers.size();
1451 boolean diff = N != NL;
1452 for (int i=0; i<NL && !diff; i++) {
1453 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
1454 }
1455 if (!diff) {
1456 for (int i=0; i<NL; i++) {
1457 mPartialTimers.get(i).mInList = true;
1458 }
1459 return;
1460 }
1461
1462 for (int i=0; i<NL; i++) {
1463 mLastPartialTimers.get(i).mInList = false;
1464 }
1465 mLastPartialTimers.clear();
1466 for (int i=0; i<N; i++) {
1467 StopwatchTimer st = mPartialTimers.get(i);
1468 st.mInList = true;
1469 mLastPartialTimers.add(st);
1470 }
1471 }
1472
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001473 public void noteProcessDiedLocked(int uid, int pid) {
1474 Uid u = mUidStats.get(uid);
1475 if (u != null) {
1476 u.mPids.remove(pid);
1477 }
1478 }
1479
1480 public long getProcessWakeTime(int uid, int pid, long realtime) {
1481 Uid u = mUidStats.get(uid);
1482 if (u != null) {
1483 Uid.Pid p = u.mPids.get(pid);
1484 if (p != null) {
1485 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
1486 }
1487 }
1488 return 0;
1489 }
1490
1491 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
1492 Uid u = mUidStats.get(uid);
1493 if (u != null) {
1494 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
1495 }
1496 }
1497
Dianne Hackborn287952c2010-09-22 22:34:31 -07001498 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
1499 Uid u = mUidStats.get(uid);
1500 if (u != null) {
1501 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
1502 }
1503 }
1504
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001505 int mSensorNesting;
1506
1507 public void noteStartSensorLocked(int uid, int sensor) {
1508 if (mSensorNesting == 0) {
1509 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
1510 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
1511 + Integer.toHexString(mHistoryCur.states));
1512 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1513 }
1514 mSensorNesting++;
1515 getUidStatsLocked(uid).noteStartSensor(sensor);
1516 }
1517
1518 public void noteStopSensorLocked(int uid, int sensor) {
1519 mSensorNesting--;
1520 if (mSensorNesting == 0) {
1521 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
1522 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
1523 + Integer.toHexString(mHistoryCur.states));
1524 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1525 }
1526 getUidStatsLocked(uid).noteStopSensor(sensor);
1527 }
1528
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001529 int mGpsNesting;
1530
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001531 public void noteStartGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001532 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001533 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001534 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
1535 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001536 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001537 }
1538 mGpsNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001539 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 }
1541
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001542 public void noteStopGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001543 mGpsNesting--;
1544 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001545 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001546 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
1547 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001548 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001549 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001550 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 public void noteScreenOnLocked() {
1554 if (!mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001555 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001556 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
1557 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001558 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 mScreenOn = true;
1560 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001561 if (mScreenBrightnessBin >= 0) {
1562 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1563 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001564
1565 // Fake a wake lock, so we consider the device waked as long
1566 // as the screen is on.
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001567 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 }
1569 }
1570
1571 public void noteScreenOffLocked() {
1572 if (mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001573 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001574 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
1575 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001576 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001577 mScreenOn = false;
1578 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001579 if (mScreenBrightnessBin >= 0) {
1580 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1581 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001582
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001583 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001584 }
1585 }
1586
1587 public void noteScreenBrightnessLocked(int brightness) {
1588 // Bin the brightness.
1589 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1590 if (bin < 0) bin = 0;
1591 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1592 if (mScreenBrightnessBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001593 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
1594 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001595 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
1596 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001597 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001598 if (mScreenOn) {
1599 if (mScreenBrightnessBin >= 0) {
1600 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1601 }
1602 mScreenBrightnessTimer[bin].startRunningLocked(this);
1603 }
1604 mScreenBrightnessBin = bin;
1605 }
1606 }
1607
Christopher Tate4cee7252010-03-19 14:50:40 -07001608 public void noteInputEventAtomic() {
1609 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001610 }
1611
1612 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001613 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 }
1615
1616 public void notePhoneOnLocked() {
1617 if (!mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001618 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001619 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
1620 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001621 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 mPhoneOn = true;
1623 mPhoneOnTimer.startRunningLocked(this);
1624 }
1625 }
1626
1627 public void notePhoneOffLocked() {
1628 if (mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001629 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001630 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
1631 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001632 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 mPhoneOn = false;
1634 mPhoneOnTimer.stopRunningLocked(this);
1635 }
1636 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001637
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001638 void stopAllSignalStrengthTimersLocked(int except) {
1639 for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
1640 if (i == except) {
1641 continue;
1642 }
1643 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1644 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
1645 }
1646 }
1647 }
1648
Dianne Hackborne4a59512010-12-07 11:08:07 -08001649 private int fixPhoneServiceState(int state, int signalBin) {
1650 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
1651 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1652 // to infer that we are scanning from other data.
1653 if (state == ServiceState.STATE_OUT_OF_SERVICE
1654 && signalBin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
1655 state = ServiceState.STATE_IN_SERVICE;
1656 }
1657 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001658
Dianne Hackborne4a59512010-12-07 11:08:07 -08001659 return state;
1660 }
1661
1662 private void updateAllPhoneStateLocked(int state, int simState, int bin) {
1663 boolean scanning = false;
1664 boolean newHistory = false;
1665
1666 mPhoneServiceStateRaw = state;
1667 mPhoneSimStateRaw = simState;
1668 mPhoneSignalStrengthBinRaw = bin;
1669
1670 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
1671 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1672 // to infer that we are scanning from other data.
1673 if (state == ServiceState.STATE_OUT_OF_SERVICE
1674 && bin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
1675 state = ServiceState.STATE_IN_SERVICE;
1676 }
1677 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001678
1679 // If the phone is powered off, stop all timers.
1680 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001681 bin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001682
Dianne Hackborne4a59512010-12-07 11:08:07 -08001683 // If we are in service, make sure the correct signal string timer is running.
1684 } else if (state == ServiceState.STATE_IN_SERVICE) {
1685 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001686
1687 // If we're out of service, we are in the lowest signal strength
1688 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07001689 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001690 scanning = true;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001691 bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001692 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001693 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001694 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001695 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
1696 + Integer.toHexString(mHistoryCur.states));
Amith Yamasanif37447b2009-10-08 18:28:01 -07001697 mPhoneSignalScanningTimer.startRunningLocked(this);
1698 }
1699 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001700
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001701 if (!scanning) {
1702 // If we are no longer scanning, then stop the scanning timer.
1703 if (mPhoneSignalScanningTimer.isRunningLocked()) {
1704 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
1705 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
1706 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001707 newHistory = true;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001708 mPhoneSignalScanningTimer.stopRunningLocked(this);
1709 }
1710 }
1711
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001712 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001713 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
1714 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08001715 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001716 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001717 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001718 mPhoneServiceState = state;
1719 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001720
1721 if (mPhoneSignalStrengthBin != bin) {
1722 if (mPhoneSignalStrengthBin >= 0) {
1723 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1724 }
1725 if (bin >= 0) {
1726 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1727 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1728 }
1729 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
1730 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
1731 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
1732 + Integer.toHexString(mHistoryCur.states));
1733 newHistory = true;
1734 } else {
1735 stopAllSignalStrengthTimersLocked(-1);
1736 }
1737 mPhoneSignalStrengthBin = bin;
1738 }
1739
1740 if (newHistory) {
1741 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1742 }
1743 }
1744
1745 /**
1746 * Telephony stack updates the phone state.
1747 * @param state phone state from ServiceState.getState()
1748 */
1749 public void notePhoneStateLocked(int state, int simState) {
1750 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001751 }
1752
Wink Savillee9b06d72009-05-18 21:47:50 -07001753 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001754 // Bin the strength.
1755 int bin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001756
Wink Savillee9b06d72009-05-18 21:47:50 -07001757 if (!signalStrength.isGsm()) {
1758 int dBm = signalStrength.getCdmaDbm();
Amith Yamasanif37447b2009-10-08 18:28:01 -07001759 if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
1760 else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD;
1761 else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE;
1762 else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR;
1763 else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Wink Savillee9b06d72009-05-18 21:47:50 -07001764 } else {
1765 int asu = signalStrength.getGsmSignalStrength();
1766 if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1767 else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
1768 else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD;
1769 else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE;
1770 else bin = SIGNAL_STRENGTH_POOR;
1771 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001772
1773 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001774 }
1775
1776 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1777 int bin = DATA_CONNECTION_NONE;
1778 if (hasData) {
1779 switch (dataType) {
1780 case TelephonyManager.NETWORK_TYPE_EDGE:
1781 bin = DATA_CONNECTION_EDGE;
1782 break;
1783 case TelephonyManager.NETWORK_TYPE_GPRS:
1784 bin = DATA_CONNECTION_GPRS;
1785 break;
1786 case TelephonyManager.NETWORK_TYPE_UMTS:
1787 bin = DATA_CONNECTION_UMTS;
1788 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001789 case TelephonyManager.NETWORK_TYPE_CDMA:
1790 bin = DATA_CONNECTION_CDMA;
1791 break;
1792 case TelephonyManager.NETWORK_TYPE_EVDO_0:
1793 bin = DATA_CONNECTION_EVDO_0;
1794 break;
1795 case TelephonyManager.NETWORK_TYPE_EVDO_A:
1796 bin = DATA_CONNECTION_EVDO_A;
1797 break;
1798 case TelephonyManager.NETWORK_TYPE_1xRTT:
1799 bin = DATA_CONNECTION_1xRTT;
1800 break;
1801 case TelephonyManager.NETWORK_TYPE_HSDPA:
1802 bin = DATA_CONNECTION_HSDPA;
1803 break;
1804 case TelephonyManager.NETWORK_TYPE_HSUPA:
1805 bin = DATA_CONNECTION_HSUPA;
1806 break;
1807 case TelephonyManager.NETWORK_TYPE_HSPA:
1808 bin = DATA_CONNECTION_HSPA;
1809 break;
1810 case TelephonyManager.NETWORK_TYPE_IDEN:
1811 bin = DATA_CONNECTION_IDEN;
1812 break;
1813 case TelephonyManager.NETWORK_TYPE_EVDO_B:
1814 bin = DATA_CONNECTION_EVDO_B;
1815 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001816 default:
1817 bin = DATA_CONNECTION_OTHER;
1818 break;
1819 }
1820 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001821 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001822 if (mPhoneDataConnectionType != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001823 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
1824 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001825 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
1826 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001827 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07001828 if (mPhoneDataConnectionType >= 0) {
1829 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
1830 }
1831 mPhoneDataConnectionType = bin;
1832 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
1833 }
1834 }
1835
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001836 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07001837 if (!mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001838 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001839 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
1840 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001841 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001842 mWifiOn = true;
1843 mWifiOnTimer.startRunningLocked(this);
1844 }
1845 }
1846
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001847 public void noteWifiOffLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07001848 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001849 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001850 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
1851 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001852 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001853 mWifiOn = false;
1854 mWifiOnTimer.stopRunningLocked(this);
1855 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001856 if (mWifiOnUid >= 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001857 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001858 mWifiOnUid = -1;
1859 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001860 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001861
1862 public void noteAudioOnLocked(int uid) {
1863 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001864 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001865 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
1866 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001867 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001868 mAudioOn = true;
1869 mAudioOnTimer.startRunningLocked(this);
1870 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001871 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001872 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001873
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001874 public void noteAudioOffLocked(int uid) {
1875 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001876 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001877 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
1878 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001879 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001880 mAudioOn = false;
1881 mAudioOnTimer.stopRunningLocked(this);
1882 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001883 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001884 }
1885
1886 public void noteVideoOnLocked(int uid) {
1887 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001888 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001889 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
1890 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001891 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001892 mVideoOn = true;
1893 mVideoOnTimer.startRunningLocked(this);
1894 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001895 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001896 }
1897
1898 public void noteVideoOffLocked(int uid) {
1899 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001900 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001901 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
1902 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001903 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001904 mVideoOn = false;
1905 mVideoOnTimer.stopRunningLocked(this);
1906 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001907 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001908 }
1909
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001910 public void noteWifiRunningLocked(WorkSource ws) {
1911 if (!mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001912 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001913 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
1914 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001915 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001916 mGlobalWifiRunning = true;
1917 mGlobalWifiRunningTimer.startRunningLocked(this);
1918 int N = ws.size();
1919 for (int i=0; i<N; i++) {
1920 getUidStatsLocked(ws.get(i)).noteWifiRunningLocked();
1921 }
1922 } else {
1923 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001924 }
1925 }
1926
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001927 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
1928 if (mGlobalWifiRunning) {
1929 int N = oldWs.size();
1930 for (int i=0; i<N; i++) {
1931 getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked();
1932 }
1933 N = newWs.size();
1934 for (int i=0; i<N; i++) {
1935 getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked();
1936 }
1937 } else {
1938 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
1939 }
1940 }
1941
1942 public void noteWifiStoppedLocked(WorkSource ws) {
1943 if (mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001944 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001945 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
1946 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001947 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001948 mGlobalWifiRunning = false;
1949 mGlobalWifiRunningTimer.stopRunningLocked(this);
1950 int N = ws.size();
1951 for (int i=0; i<N; i++) {
1952 getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked();
1953 }
1954 } else {
1955 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001956 }
1957 }
1958
The Android Open Source Project10592532009-03-18 17:39:46 -07001959 public void noteBluetoothOnLocked() {
1960 if (!mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001961 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001962 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
1963 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001964 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001965 mBluetoothOn = true;
1966 mBluetoothOnTimer.startRunningLocked(this);
1967 }
1968 }
1969
1970 public void noteBluetoothOffLocked() {
1971 if (mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001972 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001973 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
1974 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001975 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001976 mBluetoothOn = false;
1977 mBluetoothOnTimer.stopRunningLocked(this);
1978 }
1979 }
1980
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001981 int mWifiFullLockNesting = 0;
1982
The Android Open Source Project10592532009-03-18 17:39:46 -07001983 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001984 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001985 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001986 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
1987 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001988 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001989 }
1990 mWifiFullLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001991 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001992 }
1993
1994 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001995 mWifiFullLockNesting--;
1996 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001997 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001998 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
1999 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002000 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002001 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002002 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002003 }
2004
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002005 int mWifiScanLockNesting = 0;
2006
The Android Open Source Project10592532009-03-18 17:39:46 -07002007 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002008 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002009 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002010 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: "
2011 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002012 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002013 }
2014 mWifiScanLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002015 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002016 }
2017
2018 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002019 mWifiScanLockNesting--;
2020 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002021 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002022 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: "
2023 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002024 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002025 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002026 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002027 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002028
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002029 int mWifiMulticastNesting = 0;
2030
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002031 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002032 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002033 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002034 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
2035 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002036 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002037 }
2038 mWifiMulticastNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002039 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002040 }
2041
2042 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002043 mWifiMulticastNesting--;
2044 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002045 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002046 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
2047 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002048 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002049 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002050 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002051 }
2052
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002053 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2054 int N = ws.size();
2055 for (int i=0; i<N; i++) {
2056 noteFullWifiLockAcquiredLocked(ws.get(i));
2057 }
2058 }
2059
2060 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
2061 int N = ws.size();
2062 for (int i=0; i<N; i++) {
2063 noteFullWifiLockReleasedLocked(ws.get(i));
2064 }
2065 }
2066
2067 public void noteScanWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2068 int N = ws.size();
2069 for (int i=0; i<N; i++) {
2070 noteScanWifiLockAcquiredLocked(ws.get(i));
2071 }
2072 }
2073
2074 public void noteScanWifiLockReleasedFromSourceLocked(WorkSource ws) {
2075 int N = ws.size();
2076 for (int i=0; i<N; i++) {
2077 noteScanWifiLockReleasedLocked(ws.get(i));
2078 }
2079 }
2080
2081 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
2082 int N = ws.size();
2083 for (int i=0; i<N; i++) {
2084 noteWifiMulticastEnabledLocked(ws.get(i));
2085 }
2086 }
2087
2088 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
2089 int N = ws.size();
2090 for (int i=0; i<N; i++) {
2091 noteWifiMulticastDisabledLocked(ws.get(i));
2092 }
2093 }
2094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002095 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002096 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002097 }
2098
Dianne Hackborn617f8772009-03-31 15:04:46 -07002099 @Override public long getScreenBrightnessTime(int brightnessBin,
2100 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002101 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07002102 batteryRealtime, which);
2103 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002104
Dianne Hackborn617f8772009-03-31 15:04:46 -07002105 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002106 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002107 }
2108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002110 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002111 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002112
Dianne Hackborn627bba72009-03-24 22:32:56 -07002113 @Override public long getPhoneSignalStrengthTime(int strengthBin,
2114 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002115 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002116 batteryRealtime, which);
2117 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002118
2119 @Override public long getPhoneSignalScanningTime(
2120 long batteryRealtime, int which) {
2121 return mPhoneSignalScanningTimer.getTotalTimeLocked(
2122 batteryRealtime, which);
2123 }
2124
Dianne Hackborn617f8772009-03-31 15:04:46 -07002125 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002126 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002127 }
2128
Dianne Hackborn627bba72009-03-24 22:32:56 -07002129 @Override public long getPhoneDataConnectionTime(int dataType,
2130 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002131 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002132 batteryRealtime, which);
2133 }
2134
Dianne Hackborn617f8772009-03-31 15:04:46 -07002135 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002136 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002137 }
2138
The Android Open Source Project10592532009-03-18 17:39:46 -07002139 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002140 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002141 }
2142
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002143 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) {
2144 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002145 }
2146
The Android Open Source Project10592532009-03-18 17:39:46 -07002147 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002148 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002149 }
2150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002151 @Override public boolean getIsOnBattery() {
2152 return mOnBattery;
2153 }
2154
2155 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
2156 return mUidStats;
2157 }
2158
2159 /**
2160 * The statistics associated with a particular uid.
2161 */
2162 public final class Uid extends BatteryStats.Uid {
2163
2164 final int mUid;
2165 long mLoadedTcpBytesReceived;
2166 long mLoadedTcpBytesSent;
2167 long mCurrentTcpBytesReceived;
2168 long mCurrentTcpBytesSent;
2169 long mTcpBytesReceivedAtLastUnplug;
2170 long mTcpBytesSentAtLastUnplug;
2171
2172 // These are not saved/restored when parcelling, since we want
2173 // to return from the parcel with a snapshot of the state.
2174 long mStartedTcpBytesReceived = -1;
2175 long mStartedTcpBytesSent = -1;
2176
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002177 boolean mWifiRunning;
2178 StopwatchTimer mWifiRunningTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -07002179
The Android Open Source Project10592532009-03-18 17:39:46 -07002180 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002181 StopwatchTimer mFullWifiLockTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -07002182
2183 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002184 StopwatchTimer mScanWifiLockTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002185
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002186 boolean mWifiMulticastEnabled;
2187 StopwatchTimer mWifiMulticastTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002188
2189 boolean mAudioTurnedOn;
2190 StopwatchTimer mAudioTurnedOnTimer;
2191
2192 boolean mVideoTurnedOn;
2193 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002194
Dianne Hackborn617f8772009-03-31 15:04:46 -07002195 Counter[] mUserActivityCounters;
2196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002197 /**
2198 * The statistics we have collected for this uid's wake locks.
2199 */
2200 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
2201
2202 /**
2203 * The statistics we have collected for this uid's sensor activations.
2204 */
2205 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
2206
2207 /**
2208 * The statistics we have collected for this uid's processes.
2209 */
2210 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
2211
2212 /**
2213 * The statistics we have collected for this uid's processes.
2214 */
2215 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
2216
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002217 /**
2218 * The transient wake stats we have collected for this uid's pids.
2219 */
2220 final SparseArray<Pid> mPids = new SparseArray<Pid>();
2221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002222 public Uid(int uid) {
2223 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002224 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2225 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002226 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002227 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002228 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002229 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002230 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002231 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002232 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
2233 null, mUnpluggables);
2234 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
2235 null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002236 }
2237
2238 @Override
2239 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
2240 return mWakelockStats;
2241 }
2242
2243 @Override
2244 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
2245 return mSensorStats;
2246 }
2247
2248 @Override
2249 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
2250 return mProcessStats;
2251 }
2252
2253 @Override
2254 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
2255 return mPackageStats;
2256 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002257
2258 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002259 public int getUid() {
2260 return mUid;
2261 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002262
2263 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264 public long getTcpBytesReceived(int which) {
2265 if (which == STATS_LAST) {
2266 return mLoadedTcpBytesReceived;
2267 } else {
2268 long current = computeCurrentTcpBytesReceived();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002269 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 current -= mTcpBytesReceivedAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002271 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 current += mLoadedTcpBytesReceived;
2273 }
2274 return current;
2275 }
2276 }
2277
2278 public long computeCurrentTcpBytesReceived() {
2279 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08002280 ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002282
2283 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 public long getTcpBytesSent(int which) {
2285 if (which == STATS_LAST) {
2286 return mLoadedTcpBytesSent;
2287 } else {
2288 long current = computeCurrentTcpBytesSent();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002289 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 current -= mTcpBytesSentAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002291 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 current += mLoadedTcpBytesSent;
2293 }
2294 return current;
2295 }
2296 }
2297
The Android Open Source Project10592532009-03-18 17:39:46 -07002298 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002299 public void noteWifiRunningLocked() {
2300 if (!mWifiRunning) {
2301 mWifiRunning = true;
2302 if (mWifiRunningTimer == null) {
2303 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2304 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002305 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002306 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002307 }
2308 }
2309
2310 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002311 public void noteWifiStoppedLocked() {
2312 if (mWifiRunning) {
2313 mWifiRunning = false;
2314 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002315 }
2316 }
2317
2318 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002319 public void noteFullWifiLockAcquiredLocked() {
2320 if (!mFullWifiLockOut) {
2321 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002322 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002323 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002324 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002325 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002326 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2327 }
2328 }
2329
2330 @Override
2331 public void noteFullWifiLockReleasedLocked() {
2332 if (mFullWifiLockOut) {
2333 mFullWifiLockOut = false;
2334 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2335 }
2336 }
2337
2338 @Override
2339 public void noteScanWifiLockAcquiredLocked() {
2340 if (!mScanWifiLockOut) {
2341 mScanWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002342 if (mScanWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002343 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002344 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002345 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002346 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2347 }
2348 }
2349
2350 @Override
2351 public void noteScanWifiLockReleasedLocked() {
2352 if (mScanWifiLockOut) {
2353 mScanWifiLockOut = false;
2354 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2355 }
2356 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002357
2358 @Override
2359 public void noteWifiMulticastEnabledLocked() {
2360 if (!mWifiMulticastEnabled) {
2361 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002362 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002363 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002364 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002365 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002366 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
2367 }
2368 }
2369
2370 @Override
2371 public void noteWifiMulticastDisabledLocked() {
2372 if (mWifiMulticastEnabled) {
2373 mWifiMulticastEnabled = false;
2374 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
2375 }
2376 }
2377
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002378 @Override
2379 public void noteAudioTurnedOnLocked() {
2380 if (!mAudioTurnedOn) {
2381 mAudioTurnedOn = true;
2382 if (mAudioTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002383 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002384 null, mUnpluggables);
2385 }
2386 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2387 }
2388 }
2389
2390 @Override
2391 public void noteAudioTurnedOffLocked() {
2392 if (mAudioTurnedOn) {
2393 mAudioTurnedOn = false;
2394 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2395 }
2396 }
2397
2398 @Override
2399 public void noteVideoTurnedOnLocked() {
2400 if (!mVideoTurnedOn) {
2401 mVideoTurnedOn = true;
2402 if (mVideoTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002403 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002404 null, mUnpluggables);
2405 }
2406 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2407 }
2408 }
2409
2410 @Override
2411 public void noteVideoTurnedOffLocked() {
2412 if (mVideoTurnedOn) {
2413 mVideoTurnedOn = false;
2414 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2415 }
2416 }
2417
Dianne Hackborn617f8772009-03-31 15:04:46 -07002418 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002419 public long getWifiRunningTime(long batteryRealtime, int which) {
2420 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002421 return 0;
2422 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002423 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002424 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002425
2426 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002427 public long getFullWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002428 if (mFullWifiLockTimer == null) {
2429 return 0;
2430 }
Evan Millarc64edde2009-04-18 12:26:32 -07002431 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002432 }
2433
2434 @Override
2435 public long getScanWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002436 if (mScanWifiLockTimer == null) {
2437 return 0;
2438 }
Evan Millarc64edde2009-04-18 12:26:32 -07002439 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002440 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002441
2442 @Override
2443 public long getWifiMulticastTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002444 if (mWifiMulticastTimer == null) {
2445 return 0;
2446 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002447 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
2448 which);
2449 }
2450
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002451 @Override
2452 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
2453 if (mAudioTurnedOnTimer == null) {
2454 return 0;
2455 }
2456 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2457 }
2458
2459 @Override
2460 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
2461 if (mVideoTurnedOnTimer == null) {
2462 return 0;
2463 }
2464 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2465 }
2466
Dianne Hackborn617f8772009-03-31 15:04:46 -07002467 @Override
2468 public void noteUserActivityLocked(int type) {
2469 if (mUserActivityCounters == null) {
2470 initUserActivityLocked();
2471 }
2472 if (type < 0) type = 0;
2473 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
Christopher Tate4cee7252010-03-19 14:50:40 -07002474 mUserActivityCounters[type].stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002475 }
2476
2477 @Override
2478 public boolean hasUserActivity() {
2479 return mUserActivityCounters != null;
2480 }
2481
2482 @Override
2483 public int getUserActivityCount(int type, int which) {
2484 if (mUserActivityCounters == null) {
2485 return 0;
2486 }
Evan Millarc64edde2009-04-18 12:26:32 -07002487 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002488 }
2489
2490 void initUserActivityLocked() {
2491 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2492 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2493 mUserActivityCounters[i] = new Counter(mUnpluggables);
2494 }
2495 }
2496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002497 public long computeCurrentTcpBytesSent() {
2498 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08002499 ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002500 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002501
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002502 /**
2503 * Clear all stats for this uid. Returns true if the uid is completely
2504 * inactive so can be dropped.
2505 */
2506 boolean reset() {
2507 boolean active = false;
2508
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002509 if (mWifiRunningTimer != null) {
2510 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false);
2511 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002512 }
2513 if (mFullWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002514 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002515 active |= mFullWifiLockOut;
2516 }
2517 if (mScanWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002518 active |= !mScanWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002519 active |= mScanWifiLockOut;
2520 }
2521 if (mWifiMulticastTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002522 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002523 active |= mWifiMulticastEnabled;
2524 }
2525 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002526 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002527 active |= mAudioTurnedOn;
2528 }
2529 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002530 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002531 active |= mVideoTurnedOn;
2532 }
2533
2534 mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0;
2535 mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0;
2536
2537 if (mUserActivityCounters != null) {
2538 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2539 mUserActivityCounters[i].reset(false);
2540 }
2541 }
2542
2543 if (mWakelockStats.size() > 0) {
2544 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
2545 while (it.hasNext()) {
2546 Map.Entry<String, Wakelock> wakelockEntry = it.next();
2547 Wakelock wl = wakelockEntry.getValue();
2548 if (wl.reset()) {
2549 it.remove();
2550 } else {
2551 active = true;
2552 }
2553 }
2554 }
2555 if (mSensorStats.size() > 0) {
2556 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
2557 while (it.hasNext()) {
2558 Map.Entry<Integer, Sensor> sensorEntry = it.next();
2559 Sensor s = sensorEntry.getValue();
2560 if (s.reset()) {
2561 it.remove();
2562 } else {
2563 active = true;
2564 }
2565 }
2566 }
2567 if (mProcessStats.size() > 0) {
2568 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
2569 while (it.hasNext()) {
2570 Map.Entry<String, Proc> procEntry = it.next();
2571 procEntry.getValue().detach();
2572 }
2573 mProcessStats.clear();
2574 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002575 if (mPids.size() > 0) {
2576 for (int i=0; !active && i<mPids.size(); i++) {
2577 Pid pid = mPids.valueAt(i);
2578 if (pid.mWakeStart != 0) {
2579 active = true;
2580 }
2581 }
2582 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002583 if (mPackageStats.size() > 0) {
2584 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
2585 while (it.hasNext()) {
2586 Map.Entry<String, Pkg> pkgEntry = it.next();
2587 Pkg p = pkgEntry.getValue();
2588 p.detach();
2589 if (p.mServiceStats.size() > 0) {
2590 Iterator<Map.Entry<String, Pkg.Serv>> it2
2591 = p.mServiceStats.entrySet().iterator();
2592 while (it2.hasNext()) {
2593 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
2594 servEntry.getValue().detach();
2595 }
2596 }
2597 }
2598 mPackageStats.clear();
2599 }
2600
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002601 mPids.clear();
2602
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002603 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002604 if (mWifiRunningTimer != null) {
2605 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002606 }
2607 if (mFullWifiLockTimer != null) {
2608 mFullWifiLockTimer.detach();
2609 }
2610 if (mScanWifiLockTimer != null) {
2611 mScanWifiLockTimer.detach();
2612 }
2613 if (mWifiMulticastTimer != null) {
2614 mWifiMulticastTimer.detach();
2615 }
2616 if (mAudioTurnedOnTimer != null) {
2617 mAudioTurnedOnTimer.detach();
2618 }
2619 if (mVideoTurnedOnTimer != null) {
2620 mVideoTurnedOnTimer.detach();
2621 }
2622 if (mUserActivityCounters != null) {
2623 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2624 mUserActivityCounters[i].detach();
2625 }
2626 }
2627 }
2628
2629 return !active;
2630 }
2631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2633 out.writeInt(mWakelockStats.size());
2634 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
2635 out.writeString(wakelockEntry.getKey());
2636 Uid.Wakelock wakelock = wakelockEntry.getValue();
2637 wakelock.writeToParcelLocked(out, batteryRealtime);
2638 }
2639
2640 out.writeInt(mSensorStats.size());
2641 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
2642 out.writeInt(sensorEntry.getKey());
2643 Uid.Sensor sensor = sensorEntry.getValue();
2644 sensor.writeToParcelLocked(out, batteryRealtime);
2645 }
2646
2647 out.writeInt(mProcessStats.size());
2648 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
2649 out.writeString(procEntry.getKey());
2650 Uid.Proc proc = procEntry.getValue();
2651 proc.writeToParcelLocked(out);
2652 }
2653
2654 out.writeInt(mPackageStats.size());
2655 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
2656 out.writeString(pkgEntry.getKey());
2657 Uid.Pkg pkg = pkgEntry.getValue();
2658 pkg.writeToParcelLocked(out);
2659 }
2660
2661 out.writeLong(mLoadedTcpBytesReceived);
2662 out.writeLong(mLoadedTcpBytesSent);
2663 out.writeLong(computeCurrentTcpBytesReceived());
2664 out.writeLong(computeCurrentTcpBytesSent());
2665 out.writeLong(mTcpBytesReceivedAtLastUnplug);
2666 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002667 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002668 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002669 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002670 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002671 out.writeInt(0);
2672 }
2673 if (mFullWifiLockTimer != null) {
2674 out.writeInt(1);
2675 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
2676 } else {
2677 out.writeInt(0);
2678 }
2679 if (mScanWifiLockTimer != null) {
2680 out.writeInt(1);
2681 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
2682 } else {
2683 out.writeInt(0);
2684 }
2685 if (mWifiMulticastTimer != null) {
2686 out.writeInt(1);
2687 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
2688 } else {
2689 out.writeInt(0);
2690 }
2691 if (mAudioTurnedOnTimer != null) {
2692 out.writeInt(1);
2693 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
2694 } else {
2695 out.writeInt(0);
2696 }
2697 if (mVideoTurnedOnTimer != null) {
2698 out.writeInt(1);
2699 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
2700 } else {
2701 out.writeInt(0);
2702 }
2703 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002704 out.writeInt(1);
2705 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2706 mUserActivityCounters[i].writeToParcel(out);
2707 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002708 } else {
2709 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002711 }
2712
2713 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2714 int numWakelocks = in.readInt();
2715 mWakelockStats.clear();
2716 for (int j = 0; j < numWakelocks; j++) {
2717 String wakelockName = in.readString();
2718 Uid.Wakelock wakelock = new Wakelock();
2719 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002720 if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) {
2721 // We will just drop some random set of wakelocks if
2722 // the previous run of the system was an older version
2723 // that didn't impose a limit.
2724 mWakelockStats.put(wakelockName, wakelock);
2725 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002726 }
2727
2728 int numSensors = in.readInt();
2729 mSensorStats.clear();
2730 for (int k = 0; k < numSensors; k++) {
2731 int sensorNumber = in.readInt();
2732 Uid.Sensor sensor = new Sensor(sensorNumber);
2733 sensor.readFromParcelLocked(mUnpluggables, in);
2734 mSensorStats.put(sensorNumber, sensor);
2735 }
2736
2737 int numProcs = in.readInt();
2738 mProcessStats.clear();
2739 for (int k = 0; k < numProcs; k++) {
2740 String processName = in.readString();
2741 Uid.Proc proc = new Proc();
2742 proc.readFromParcelLocked(in);
2743 mProcessStats.put(processName, proc);
2744 }
2745
2746 int numPkgs = in.readInt();
2747 mPackageStats.clear();
2748 for (int l = 0; l < numPkgs; l++) {
2749 String packageName = in.readString();
2750 Uid.Pkg pkg = new Pkg();
2751 pkg.readFromParcelLocked(in);
2752 mPackageStats.put(packageName, pkg);
2753 }
2754
2755 mLoadedTcpBytesReceived = in.readLong();
2756 mLoadedTcpBytesSent = in.readLong();
2757 mCurrentTcpBytesReceived = in.readLong();
2758 mCurrentTcpBytesSent = in.readLong();
2759 mTcpBytesReceivedAtLastUnplug = in.readLong();
2760 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002761 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002762 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002763 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2764 mWifiRunningTimers, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002765 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002766 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002767 }
2768 mFullWifiLockOut = false;
2769 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002770 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002771 mFullWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002772 } else {
2773 mFullWifiLockTimer = null;
2774 }
2775 mScanWifiLockOut = false;
2776 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002777 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002778 mScanWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002779 } else {
2780 mScanWifiLockTimer = null;
2781 }
2782 mWifiMulticastEnabled = false;
2783 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002784 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002785 mWifiMulticastTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002786 } else {
2787 mWifiMulticastTimer = null;
2788 }
2789 mAudioTurnedOn = false;
2790 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002791 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002792 null, mUnpluggables, in);
2793 } else {
2794 mAudioTurnedOnTimer = null;
2795 }
2796 mVideoTurnedOn = false;
2797 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002798 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002799 null, mUnpluggables, in);
2800 } else {
2801 mVideoTurnedOnTimer = null;
2802 }
2803 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002804 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2805 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2806 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
2807 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002808 } else {
2809 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07002810 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002811 }
2812
2813 /**
2814 * The statistics associated with a particular wake lock.
2815 */
2816 public final class Wakelock extends BatteryStats.Uid.Wakelock {
2817 /**
2818 * How long (in ms) this uid has been keeping the device partially awake.
2819 */
Evan Millarc64edde2009-04-18 12:26:32 -07002820 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821
2822 /**
2823 * How long (in ms) this uid has been keeping the device fully awake.
2824 */
Evan Millarc64edde2009-04-18 12:26:32 -07002825 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826
2827 /**
2828 * How long (in ms) this uid has had a window keeping the device awake.
2829 */
Evan Millarc64edde2009-04-18 12:26:32 -07002830 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831
2832 /**
2833 * Reads a possibly null Timer from a Parcel. The timer is associated with the
2834 * proper timer pool from the given BatteryStatsImpl object.
2835 *
2836 * @param in the Parcel to be read from.
2837 * return a new Timer, or null.
2838 */
Evan Millarc64edde2009-04-18 12:26:32 -07002839 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002840 ArrayList<Unpluggable> unpluggables, Parcel in) {
2841 if (in.readInt() == 0) {
2842 return null;
2843 }
2844
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002845 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002846 }
2847
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002848 boolean reset() {
2849 boolean wlactive = false;
2850 if (mTimerFull != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002851 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002852 }
2853 if (mTimerPartial != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002854 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002855 }
2856 if (mTimerWindow != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002857 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002858 }
2859 if (!wlactive) {
2860 if (mTimerFull != null) {
2861 mTimerFull.detach();
2862 mTimerFull = null;
2863 }
2864 if (mTimerPartial != null) {
2865 mTimerPartial.detach();
2866 mTimerPartial = null;
2867 }
2868 if (mTimerWindow != null) {
2869 mTimerWindow.detach();
2870 mTimerWindow = null;
2871 }
2872 }
2873 return !wlactive;
2874 }
2875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002876 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2877 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
2878 mPartialTimers, unpluggables, in);
2879 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
2880 mFullTimers, unpluggables, in);
2881 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
2882 mWindowTimers, unpluggables, in);
2883 }
2884
2885 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2886 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
2887 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
2888 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
2889 }
2890
2891 @Override
2892 public Timer getWakeTime(int type) {
2893 switch (type) {
2894 case WAKE_TYPE_FULL: return mTimerFull;
2895 case WAKE_TYPE_PARTIAL: return mTimerPartial;
2896 case WAKE_TYPE_WINDOW: return mTimerWindow;
2897 default: throw new IllegalArgumentException("type = " + type);
2898 }
2899 }
2900 }
2901
2902 public final class Sensor extends BatteryStats.Uid.Sensor {
2903 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07002904 StopwatchTimer mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002905
2906 public Sensor(int handle) {
2907 mHandle = handle;
2908 }
2909
Evan Millarc64edde2009-04-18 12:26:32 -07002910 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002911 Parcel in) {
2912 if (in.readInt() == 0) {
2913 return null;
2914 }
2915
Evan Millarc64edde2009-04-18 12:26:32 -07002916 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002918 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 mSensorTimers.put(mHandle, pool);
2920 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002921 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 }
2923
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002924 boolean reset() {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002925 if (mTimer.reset(BatteryStatsImpl.this, true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002926 mTimer = null;
2927 return true;
2928 }
2929 return false;
2930 }
2931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002932 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2933 mTimer = readTimerFromParcel(unpluggables, in);
2934 }
2935
2936 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2937 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
2938 }
2939
2940 @Override
2941 public Timer getSensorTime() {
2942 return mTimer;
2943 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002944
2945 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002946 public int getHandle() {
2947 return mHandle;
2948 }
2949 }
2950
2951 /**
2952 * The statistics associated with a particular process.
2953 */
2954 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
2955 /**
2956 * Total time (in 1/100 sec) spent executing in user code.
2957 */
2958 long mUserTime;
2959
2960 /**
2961 * Total time (in 1/100 sec) spent executing in kernel code.
2962 */
2963 long mSystemTime;
2964
2965 /**
2966 * Number of times the process has been started.
2967 */
2968 int mStarts;
2969
2970 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002971 * Amount of time the process was running in the foreground.
2972 */
2973 long mForegroundTime;
2974
2975 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002976 * The amount of user time loaded from a previous save.
2977 */
2978 long mLoadedUserTime;
2979
2980 /**
2981 * The amount of system time loaded from a previous save.
2982 */
2983 long mLoadedSystemTime;
2984
2985 /**
2986 * The number of times the process has started from a previous save.
2987 */
2988 int mLoadedStarts;
2989
2990 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002991 * The amount of foreground time loaded from a previous save.
2992 */
2993 long mLoadedForegroundTime;
2994
2995 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002996 * The amount of user time loaded from the previous run.
2997 */
2998 long mLastUserTime;
2999
3000 /**
3001 * The amount of system time loaded from the previous run.
3002 */
3003 long mLastSystemTime;
3004
3005 /**
3006 * The number of times the process has started from the previous run.
3007 */
3008 int mLastStarts;
3009
3010 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003011 * The amount of foreground time loaded from the previous run
3012 */
3013 long mLastForegroundTime;
3014
3015 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003016 * The amount of user time when last unplugged.
3017 */
3018 long mUnpluggedUserTime;
3019
3020 /**
3021 * The amount of system time when last unplugged.
3022 */
3023 long mUnpluggedSystemTime;
3024
3025 /**
3026 * The number of times the process has started before unplugged.
3027 */
3028 int mUnpluggedStarts;
3029
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003030 /**
3031 * The amount of foreground time since unplugged.
3032 */
3033 long mUnpluggedForegroundTime;
3034
Amith Yamasanie43530a2009-08-21 13:11:37 -07003035 SamplingCounter[] mSpeedBins;
3036
Dianne Hackborn287952c2010-09-22 22:34:31 -07003037 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003039 Proc() {
3040 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003041 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003044 public void unplug(long batteryUptime, long batteryRealtime) {
3045 mUnpluggedUserTime = mUserTime;
3046 mUnpluggedSystemTime = mSystemTime;
3047 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003048 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 }
3050
3051 public void plug(long batteryUptime, long batteryRealtime) {
3052 }
3053
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003054 void detach() {
3055 mUnpluggables.remove(this);
3056 for (int i = 0; i < mSpeedBins.length; i++) {
3057 SamplingCounter c = mSpeedBins[i];
3058 if (c != null) {
3059 mUnpluggables.remove(c);
3060 mSpeedBins[i] = null;
3061 }
3062 }
3063 }
3064
Dianne Hackborn287952c2010-09-22 22:34:31 -07003065 public int countExcessivePowers() {
3066 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003067 }
3068
Dianne Hackborn287952c2010-09-22 22:34:31 -07003069 public ExcessivePower getExcessivePower(int i) {
3070 if (mExcessivePower != null) {
3071 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003072 }
3073 return null;
3074 }
3075
3076 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003077 if (mExcessivePower == null) {
3078 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003079 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07003080 ExcessivePower ew = new ExcessivePower();
3081 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003082 ew.overTime = overTime;
3083 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07003084 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003085 }
3086
Dianne Hackborn287952c2010-09-22 22:34:31 -07003087 public void addExcessiveCpu(long overTime, long usedTime) {
3088 if (mExcessivePower == null) {
3089 mExcessivePower = new ArrayList<ExcessivePower>();
3090 }
3091 ExcessivePower ew = new ExcessivePower();
3092 ew.type = ExcessivePower.TYPE_CPU;
3093 ew.overTime = overTime;
3094 ew.usedTime = usedTime;
3095 mExcessivePower.add(ew);
3096 }
3097
3098 void writeExcessivePowerToParcelLocked(Parcel out) {
3099 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003100 out.writeInt(0);
3101 return;
3102 }
3103
Dianne Hackborn287952c2010-09-22 22:34:31 -07003104 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003105 out.writeInt(N);
3106 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003107 ExcessivePower ew = mExcessivePower.get(i);
3108 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003109 out.writeLong(ew.overTime);
3110 out.writeLong(ew.usedTime);
3111 }
3112 }
3113
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003114 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003115 final int N = in.readInt();
3116 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003117 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003118 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003119 }
3120
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003121 if (N > 10000) {
3122 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
3123 return false;
3124 }
3125
Dianne Hackborn287952c2010-09-22 22:34:31 -07003126 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003127 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003128 ExcessivePower ew = new ExcessivePower();
3129 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003130 ew.overTime = in.readLong();
3131 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07003132 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003133 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003134 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003135 }
3136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003137 void writeToParcelLocked(Parcel out) {
3138 out.writeLong(mUserTime);
3139 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003140 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003141 out.writeInt(mStarts);
3142 out.writeLong(mLoadedUserTime);
3143 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003144 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003145 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003146 out.writeLong(mUnpluggedUserTime);
3147 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003148 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003149 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003150
3151 out.writeInt(mSpeedBins.length);
3152 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003153 SamplingCounter c = mSpeedBins[i];
3154 if (c != null) {
3155 out.writeInt(1);
3156 c.writeToParcel(out);
3157 } else {
3158 out.writeInt(0);
3159 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003160 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003161
Dianne Hackborn287952c2010-09-22 22:34:31 -07003162 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003163 }
3164
3165 void readFromParcelLocked(Parcel in) {
3166 mUserTime = in.readLong();
3167 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003168 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003169 mStarts = in.readInt();
3170 mLoadedUserTime = in.readLong();
3171 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003172 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003174 mLastUserTime = 0;
3175 mLastSystemTime = 0;
3176 mLastForegroundTime = 0;
3177 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 mUnpluggedUserTime = in.readLong();
3179 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003180 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003181 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07003182
3183 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003184 int steps = getCpuSpeedSteps();
3185 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07003186 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003187 if (in.readInt() != 0) {
3188 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
3189 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003190 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003191
Dianne Hackborn287952c2010-09-22 22:34:31 -07003192 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003193 }
3194
3195 public BatteryStatsImpl getBatteryStats() {
3196 return BatteryStatsImpl.this;
3197 }
3198
3199 public void addCpuTimeLocked(int utime, int stime) {
3200 mUserTime += utime;
3201 mSystemTime += stime;
3202 }
3203
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003204 public void addForegroundTimeLocked(long ttime) {
3205 mForegroundTime += ttime;
3206 }
3207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 public void incStartsLocked() {
3209 mStarts++;
3210 }
3211
3212 @Override
3213 public long getUserTime(int which) {
3214 long val;
3215 if (which == STATS_LAST) {
3216 val = mLastUserTime;
3217 } else {
3218 val = mUserTime;
3219 if (which == STATS_CURRENT) {
3220 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003221 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003222 val -= mUnpluggedUserTime;
3223 }
3224 }
3225 return val;
3226 }
3227
3228 @Override
3229 public long getSystemTime(int which) {
3230 long val;
3231 if (which == STATS_LAST) {
3232 val = mLastSystemTime;
3233 } else {
3234 val = mSystemTime;
3235 if (which == STATS_CURRENT) {
3236 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003237 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003238 val -= mUnpluggedSystemTime;
3239 }
3240 }
3241 return val;
3242 }
3243
3244 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003245 public long getForegroundTime(int which) {
3246 long val;
3247 if (which == STATS_LAST) {
3248 val = mLastForegroundTime;
3249 } else {
3250 val = mForegroundTime;
3251 if (which == STATS_CURRENT) {
3252 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003253 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003254 val -= mUnpluggedForegroundTime;
3255 }
3256 }
3257 return val;
3258 }
3259
3260 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003261 public int getStarts(int which) {
3262 int val;
3263 if (which == STATS_LAST) {
3264 val = mLastStarts;
3265 } else {
3266 val = mStarts;
3267 if (which == STATS_CURRENT) {
3268 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003269 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003270 val -= mUnpluggedStarts;
3271 }
3272 }
3273 return val;
3274 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003275
3276 /* Called by ActivityManagerService when CPU times are updated. */
3277 public void addSpeedStepTimes(long[] values) {
3278 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003279 long amt = values[i];
3280 if (amt != 0) {
3281 SamplingCounter c = mSpeedBins[i];
3282 if (c == null) {
3283 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
3284 }
3285 c.addCountAtomic(values[i]);
3286 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003287 }
3288 }
3289
3290 @Override
3291 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
3292 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003293 SamplingCounter c = mSpeedBins[speedStep];
3294 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07003295 } else {
3296 return 0;
3297 }
3298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003299 }
3300
3301 /**
3302 * The statistics associated with a particular package.
3303 */
3304 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
3305 /**
3306 * Number of times this package has done something that could wake up the
3307 * device from sleep.
3308 */
3309 int mWakeups;
3310
3311 /**
3312 * Number of things that could wake up the device loaded from a
3313 * previous save.
3314 */
3315 int mLoadedWakeups;
3316
3317 /**
3318 * Number of things that could wake up the device as of the
3319 * last run.
3320 */
3321 int mLastWakeups;
3322
3323 /**
3324 * Number of things that could wake up the device as of the
3325 * last run.
3326 */
3327 int mUnpluggedWakeups;
3328
3329 /**
3330 * The statics we have collected for this package's services.
3331 */
3332 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
3333
3334 Pkg() {
3335 mUnpluggables.add(this);
3336 }
3337
3338 public void unplug(long batteryUptime, long batteryRealtime) {
3339 mUnpluggedWakeups = mWakeups;
3340 }
3341
3342 public void plug(long batteryUptime, long batteryRealtime) {
3343 }
3344
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003345 void detach() {
3346 mUnpluggables.remove(this);
3347 }
3348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 void readFromParcelLocked(Parcel in) {
3350 mWakeups = in.readInt();
3351 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003352 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 mUnpluggedWakeups = in.readInt();
3354
3355 int numServs = in.readInt();
3356 mServiceStats.clear();
3357 for (int m = 0; m < numServs; m++) {
3358 String serviceName = in.readString();
3359 Uid.Pkg.Serv serv = new Serv();
3360 mServiceStats.put(serviceName, serv);
3361
3362 serv.readFromParcelLocked(in);
3363 }
3364 }
3365
3366 void writeToParcelLocked(Parcel out) {
3367 out.writeInt(mWakeups);
3368 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 out.writeInt(mUnpluggedWakeups);
3370
3371 out.writeInt(mServiceStats.size());
3372 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
3373 out.writeString(servEntry.getKey());
3374 Uid.Pkg.Serv serv = servEntry.getValue();
3375
3376 serv.writeToParcelLocked(out);
3377 }
3378 }
3379
3380 @Override
3381 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
3382 return mServiceStats;
3383 }
3384
3385 @Override
3386 public int getWakeups(int which) {
3387 int val;
3388 if (which == STATS_LAST) {
3389 val = mLastWakeups;
3390 } else {
3391 val = mWakeups;
3392 if (which == STATS_CURRENT) {
3393 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003394 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003395 val -= mUnpluggedWakeups;
3396 }
3397 }
3398
3399 return val;
3400 }
3401
3402 /**
3403 * The statistics associated with a particular service.
3404 */
3405 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
3406 /**
3407 * Total time (ms in battery uptime) the service has been left started.
3408 */
3409 long mStartTime;
3410
3411 /**
3412 * If service has been started and not yet stopped, this is
3413 * when it was started.
3414 */
3415 long mRunningSince;
3416
3417 /**
3418 * True if we are currently running.
3419 */
3420 boolean mRunning;
3421
3422 /**
3423 * Total number of times startService() has been called.
3424 */
3425 int mStarts;
3426
3427 /**
3428 * Total time (ms in battery uptime) the service has been left launched.
3429 */
3430 long mLaunchedTime;
3431
3432 /**
3433 * If service has been launched and not yet exited, this is
3434 * when it was launched (ms in battery uptime).
3435 */
3436 long mLaunchedSince;
3437
3438 /**
3439 * True if we are currently launched.
3440 */
3441 boolean mLaunched;
3442
3443 /**
3444 * Total number times the service has been launched.
3445 */
3446 int mLaunches;
3447
3448 /**
3449 * The amount of time spent started loaded from a previous save
3450 * (ms in battery uptime).
3451 */
3452 long mLoadedStartTime;
3453
3454 /**
3455 * The number of starts loaded from a previous save.
3456 */
3457 int mLoadedStarts;
3458
3459 /**
3460 * The number of launches loaded from a previous save.
3461 */
3462 int mLoadedLaunches;
3463
3464 /**
3465 * The amount of time spent started as of the last run (ms
3466 * in battery uptime).
3467 */
3468 long mLastStartTime;
3469
3470 /**
3471 * The number of starts as of the last run.
3472 */
3473 int mLastStarts;
3474
3475 /**
3476 * The number of launches as of the last run.
3477 */
3478 int mLastLaunches;
3479
3480 /**
3481 * The amount of time spent started when last unplugged (ms
3482 * in battery uptime).
3483 */
3484 long mUnpluggedStartTime;
3485
3486 /**
3487 * The number of starts when last unplugged.
3488 */
3489 int mUnpluggedStarts;
3490
3491 /**
3492 * The number of launches when last unplugged.
3493 */
3494 int mUnpluggedLaunches;
3495
3496 Serv() {
3497 mUnpluggables.add(this);
3498 }
3499
3500 public void unplug(long batteryUptime, long batteryRealtime) {
3501 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
3502 mUnpluggedStarts = mStarts;
3503 mUnpluggedLaunches = mLaunches;
3504 }
3505
3506 public void plug(long batteryUptime, long batteryRealtime) {
3507 }
3508
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003509 void detach() {
3510 mUnpluggables.remove(this);
3511 }
3512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 void readFromParcelLocked(Parcel in) {
3514 mStartTime = in.readLong();
3515 mRunningSince = in.readLong();
3516 mRunning = in.readInt() != 0;
3517 mStarts = in.readInt();
3518 mLaunchedTime = in.readLong();
3519 mLaunchedSince = in.readLong();
3520 mLaunched = in.readInt() != 0;
3521 mLaunches = in.readInt();
3522 mLoadedStartTime = in.readLong();
3523 mLoadedStarts = in.readInt();
3524 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003525 mLastStartTime = 0;
3526 mLastStarts = 0;
3527 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003528 mUnpluggedStartTime = in.readLong();
3529 mUnpluggedStarts = in.readInt();
3530 mUnpluggedLaunches = in.readInt();
3531 }
3532
3533 void writeToParcelLocked(Parcel out) {
3534 out.writeLong(mStartTime);
3535 out.writeLong(mRunningSince);
3536 out.writeInt(mRunning ? 1 : 0);
3537 out.writeInt(mStarts);
3538 out.writeLong(mLaunchedTime);
3539 out.writeLong(mLaunchedSince);
3540 out.writeInt(mLaunched ? 1 : 0);
3541 out.writeInt(mLaunches);
3542 out.writeLong(mLoadedStartTime);
3543 out.writeInt(mLoadedStarts);
3544 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003545 out.writeLong(mUnpluggedStartTime);
3546 out.writeInt(mUnpluggedStarts);
3547 out.writeInt(mUnpluggedLaunches);
3548 }
3549
3550 long getLaunchTimeToNowLocked(long batteryUptime) {
3551 if (!mLaunched) return mLaunchedTime;
3552 return mLaunchedTime + batteryUptime - mLaunchedSince;
3553 }
3554
3555 long getStartTimeToNowLocked(long batteryUptime) {
3556 if (!mRunning) return mStartTime;
3557 return mStartTime + batteryUptime - mRunningSince;
3558 }
3559
3560 public void startLaunchedLocked() {
3561 if (!mLaunched) {
3562 mLaunches++;
3563 mLaunchedSince = getBatteryUptimeLocked();
3564 mLaunched = true;
3565 }
3566 }
3567
3568 public void stopLaunchedLocked() {
3569 if (mLaunched) {
3570 long time = getBatteryUptimeLocked() - mLaunchedSince;
3571 if (time > 0) {
3572 mLaunchedTime += time;
3573 } else {
3574 mLaunches--;
3575 }
3576 mLaunched = false;
3577 }
3578 }
3579
3580 public void startRunningLocked() {
3581 if (!mRunning) {
3582 mStarts++;
3583 mRunningSince = getBatteryUptimeLocked();
3584 mRunning = true;
3585 }
3586 }
3587
3588 public void stopRunningLocked() {
3589 if (mRunning) {
3590 long time = getBatteryUptimeLocked() - mRunningSince;
3591 if (time > 0) {
3592 mStartTime += time;
3593 } else {
3594 mStarts--;
3595 }
3596 mRunning = false;
3597 }
3598 }
3599
3600 public BatteryStatsImpl getBatteryStats() {
3601 return BatteryStatsImpl.this;
3602 }
3603
3604 @Override
3605 public int getLaunches(int which) {
3606 int val;
3607
3608 if (which == STATS_LAST) {
3609 val = mLastLaunches;
3610 } else {
3611 val = mLaunches;
3612 if (which == STATS_CURRENT) {
3613 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003614 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 val -= mUnpluggedLaunches;
3616 }
3617 }
3618
3619 return val;
3620 }
3621
3622 @Override
3623 public long getStartTime(long now, int which) {
3624 long val;
3625 if (which == STATS_LAST) {
3626 val = mLastStartTime;
3627 } else {
3628 val = getStartTimeToNowLocked(now);
3629 if (which == STATS_CURRENT) {
3630 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003631 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 val -= mUnpluggedStartTime;
3633 }
3634 }
3635
3636 return val;
3637 }
3638
3639 @Override
3640 public int getStarts(int which) {
3641 int val;
3642 if (which == STATS_LAST) {
3643 val = mLastStarts;
3644 } else {
3645 val = mStarts;
3646 if (which == STATS_CURRENT) {
3647 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003648 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003649 val -= mUnpluggedStarts;
3650 }
3651 }
3652
3653 return val;
3654 }
3655 }
3656
3657 public BatteryStatsImpl getBatteryStats() {
3658 return BatteryStatsImpl.this;
3659 }
3660
3661 public void incWakeupsLocked() {
3662 mWakeups++;
3663 }
3664
3665 final Serv newServiceStatsLocked() {
3666 return new Serv();
3667 }
3668 }
3669
3670 /**
3671 * Retrieve the statistics object for a particular process, creating
3672 * if needed.
3673 */
3674 public Proc getProcessStatsLocked(String name) {
3675 Proc ps = mProcessStats.get(name);
3676 if (ps == null) {
3677 ps = new Proc();
3678 mProcessStats.put(name, ps);
3679 }
3680
3681 return ps;
3682 }
3683
Dianne Hackbornb5e31652010-09-07 12:13:55 -07003684 public SparseArray<? extends Pid> getPidStats() {
3685 return mPids;
3686 }
3687
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003688 public Pid getPidStatsLocked(int pid) {
3689 Pid p = mPids.get(pid);
3690 if (p == null) {
3691 p = new Pid();
3692 mPids.put(pid, p);
3693 }
3694 return p;
3695 }
3696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 /**
3698 * Retrieve the statistics object for a particular service, creating
3699 * if needed.
3700 */
3701 public Pkg getPackageStatsLocked(String name) {
3702 Pkg ps = mPackageStats.get(name);
3703 if (ps == null) {
3704 ps = new Pkg();
3705 mPackageStats.put(name, ps);
3706 }
3707
3708 return ps;
3709 }
3710
3711 /**
3712 * Retrieve the statistics object for a particular service, creating
3713 * if needed.
3714 */
3715 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
3716 Pkg ps = getPackageStatsLocked(pkg);
3717 Pkg.Serv ss = ps.mServiceStats.get(serv);
3718 if (ss == null) {
3719 ss = ps.newServiceStatsLocked();
3720 ps.mServiceStats.put(serv, ss);
3721 }
3722
3723 return ss;
3724 }
3725
Evan Millarc64edde2009-04-18 12:26:32 -07003726 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003727 Wakelock wl = mWakelockStats.get(name);
3728 if (wl == null) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08003729 if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) {
3730 name = BATCHED_WAKELOCK_NAME;
3731 wl = mWakelockStats.get(name);
3732 }
3733 if (wl == null) {
3734 wl = new Wakelock();
3735 mWakelockStats.put(name, wl);
3736 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 }
Evan Millarc64edde2009-04-18 12:26:32 -07003738 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003739 switch (type) {
3740 case WAKE_TYPE_PARTIAL:
3741 t = wl.mTimerPartial;
3742 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003743 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
3744 mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003745 wl.mTimerPartial = t;
3746 }
3747 return t;
3748 case WAKE_TYPE_FULL:
3749 t = wl.mTimerFull;
3750 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003751 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
3752 mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003753 wl.mTimerFull = t;
3754 }
3755 return t;
3756 case WAKE_TYPE_WINDOW:
3757 t = wl.mTimerWindow;
3758 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003759 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
3760 mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 wl.mTimerWindow = t;
3762 }
3763 return t;
3764 default:
3765 throw new IllegalArgumentException("type=" + type);
3766 }
3767 }
3768
Evan Millarc64edde2009-04-18 12:26:32 -07003769 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003770 Sensor se = mSensorStats.get(sensor);
3771 if (se == null) {
3772 if (!create) {
3773 return null;
3774 }
3775 se = new Sensor(sensor);
3776 mSensorStats.put(sensor, se);
3777 }
Evan Millarc64edde2009-04-18 12:26:32 -07003778 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003779 if (t != null) {
3780 return t;
3781 }
Evan Millarc64edde2009-04-18 12:26:32 -07003782 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003783 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003784 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003785 mSensorTimers.put(sensor, timers);
3786 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003787 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003788 se.mTimer = t;
3789 return t;
3790 }
3791
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003792 public void noteStartWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003793 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003794 if (t != null) {
3795 t.startRunningLocked(BatteryStatsImpl.this);
3796 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003797 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003798 Pid p = getPidStatsLocked(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003799 if (p.mWakeStart == 0) {
3800 p.mWakeStart = SystemClock.elapsedRealtime();
3801 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003802 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003803 }
3804
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003805 public void noteStopWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003806 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003807 if (t != null) {
3808 t.stopRunningLocked(BatteryStatsImpl.this);
3809 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003810 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003811 Pid p = mPids.get(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003812 if (p != null && p.mWakeStart != 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003813 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
3814 p.mWakeStart = 0;
3815 }
3816 }
3817 }
3818
3819 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
3820 Proc p = getProcessStatsLocked(proc);
3821 if (p != null) {
3822 p.addExcessiveWake(overTime, usedTime);
3823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003824 }
3825
Dianne Hackborn287952c2010-09-22 22:34:31 -07003826 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
3827 Proc p = getProcessStatsLocked(proc);
3828 if (p != null) {
3829 p.addExcessiveCpu(overTime, usedTime);
3830 }
3831 }
3832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003833 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07003834 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 if (t != null) {
3836 t.startRunningLocked(BatteryStatsImpl.this);
3837 }
3838 }
3839
3840 public void noteStopSensor(int sensor) {
3841 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07003842 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003843 if (t != null) {
3844 t.stopRunningLocked(BatteryStatsImpl.this);
3845 }
3846 }
3847
3848 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07003849 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003850 if (t != null) {
3851 t.startRunningLocked(BatteryStatsImpl.this);
3852 }
3853 }
3854
3855 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07003856 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003857 if (t != null) {
3858 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003860 }
3861
3862 public BatteryStatsImpl getBatteryStats() {
3863 return BatteryStatsImpl.this;
3864 }
3865 }
3866
3867 public BatteryStatsImpl(String filename) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003868 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003869 mHandler = new MyHandler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870 mStartCount++;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003871 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003872 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003873 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003874 }
3875 mInputEventCounter = new Counter(mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003876 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003877 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003878 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003879 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003880 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003881 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003882 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003883 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003884 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003885 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003886 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
3887 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
3888 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003890 initTimes();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003891 mTrackBatteryPastUptime = 0;
3892 mTrackBatteryPastRealtime = 0;
3893 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
3894 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
3895 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
3896 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07003897 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003898 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07003899 mDischargeCurrentLevel = 0;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003900 mLowDischargeAmountSinceCharge = 0;
3901 mHighDischargeAmountSinceCharge = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003902 }
3903
3904 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003905 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003906 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003907 readFromParcel(p);
3908 }
3909
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003910 public void setCallback(BatteryCallback cb) {
3911 mCallback = cb;
3912 }
3913
Amith Yamasanie43530a2009-08-21 13:11:37 -07003914 public void setNumSpeedSteps(int steps) {
3915 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
3916 }
3917
Amith Yamasanif37447b2009-10-08 18:28:01 -07003918 public void setRadioScanningTimeout(long timeout) {
3919 if (mPhoneSignalScanningTimer != null) {
3920 mPhoneSignalScanningTimer.setTimeout(timeout);
3921 }
3922 }
3923
Dianne Hackbornce2ef762010-09-20 11:39:14 -07003924 private HistoryItem mHistoryIterator;
3925
3926 public boolean startIteratingHistoryLocked() {
3927 return (mHistoryIterator = mHistory) != null;
3928 }
3929
3930 public boolean getNextHistoryLocked(HistoryItem out) {
3931 HistoryItem cur = mHistoryIterator;
3932 if (cur == null) {
3933 return false;
3934 }
3935 out.setTo(cur);
3936 mHistoryIterator = cur.next;
3937 return true;
3938 }
3939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003941 public HistoryItem getHistory() {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003942 return mHistory;
3943 }
3944
3945 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07003946 public long getHistoryBaseTime() {
3947 return mHistoryBaseTime;
3948 }
3949
3950 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 public int getStartCount() {
3952 return mStartCount;
3953 }
3954
3955 public boolean isOnBattery() {
3956 return mOnBattery;
3957 }
3958
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003959 public boolean isScreenOn() {
3960 return mScreenOn;
3961 }
3962
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003963 void initTimes() {
3964 mBatteryRealtime = mTrackBatteryPastUptime = 0;
3965 mBatteryUptime = mTrackBatteryPastRealtime = 0;
3966 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
3967 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
3968 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
3969 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
3970 }
3971
3972 public void resetAllStatsLocked() {
3973 mStartCount = 0;
3974 initTimes();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003975 mScreenOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003976 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003977 mScreenBrightnessTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003978 }
3979 mInputEventCounter.reset(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003980 mPhoneOnTimer.reset(this, false);
3981 mAudioOnTimer.reset(this, false);
3982 mVideoOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003983 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003984 mPhoneSignalStrengthsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003985 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003986 mPhoneSignalScanningTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003987 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003988 mPhoneDataConnectionsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003989 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003990 mWifiOnTimer.reset(this, false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003991 mGlobalWifiRunningTimer.reset(this, false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003992 mBluetoothOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003993
3994 for (int i=0; i<mUidStats.size(); i++) {
3995 if (mUidStats.valueAt(i).reset()) {
3996 mUidStats.remove(mUidStats.keyAt(i));
3997 i--;
3998 }
3999 }
4000
4001 if (mKernelWakelockStats.size() > 0) {
4002 for (SamplingTimer timer : mKernelWakelockStats.values()) {
4003 mUnpluggables.remove(timer);
4004 }
4005 mKernelWakelockStats.clear();
4006 }
4007
Dianne Hackborne4a59512010-12-07 11:08:07 -08004008 mLowDischargeAmountSinceCharge = 0;
4009 mHighDischargeAmountSinceCharge = 0;
4010
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004011 clearHistoryLocked();
4012 }
4013
4014 void setOnBattery(boolean onBattery, int oldStatus, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 synchronized(this) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004016 boolean doWrite = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004017 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
4018 m.arg1 = onBattery ? 1 : 0;
4019 mHandler.sendMessage(m);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004020 mOnBattery = mOnBatteryInternal = onBattery;
4021
4022 long uptime = SystemClock.uptimeMillis() * 1000;
4023 long mSecRealtime = SystemClock.elapsedRealtime();
4024 long realtime = mSecRealtime * 1000;
4025 if (onBattery) {
4026 // We will reset our status if we are unplugging after the
4027 // battery was last full, or the level is at 100, or
4028 // we have gone through a significant charge (from a very low
4029 // level to a now very high level).
4030 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
Dianne Hackborn266e6072010-10-20 12:24:51 -07004031 || level >= 95
Dianne Hackborne4a59512010-12-07 11:08:07 -08004032 || (mDischargeCurrentLevel < 20 && level >= 80)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004033 doWrite = true;
4034 resetAllStatsLocked();
4035 mDischargeStartLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004036 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004037 updateKernelWakelocksLocked();
4038 mHistoryCur.batteryLevel = (byte)level;
4039 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4040 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
4041 + Integer.toHexString(mHistoryCur.states));
4042 addHistoryRecordLocked(mSecRealtime);
4043 mTrackBatteryUptimeStart = uptime;
4044 mTrackBatteryRealtimeStart = realtime;
4045 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
4046 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
4047 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
4048 doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
4049 } else {
4050 updateKernelWakelocksLocked();
4051 mHistoryCur.batteryLevel = (byte)level;
4052 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4053 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
4054 + Integer.toHexString(mHistoryCur.states));
4055 addHistoryRecordLocked(mSecRealtime);
4056 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
4057 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
4058 mDischargeCurrentLevel = level;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004059 if (level < mDischargeUnplugLevel) {
Dianne Hackborn99d04522010-08-20 13:43:00 -07004060 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
4061 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004062 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004063 doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
4064 }
4065 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
4066 if (mFile != null) {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004067 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004068 }
4069 }
4070 }
4071 }
Evan Millar633a1742009-04-02 16:36:33 -07004072
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004073 // This should probably be exposed in the API, though it's not critical
4074 private static final int BATTERY_PLUGGED_NONE = 0;
4075
4076 public void setBatteryState(int status, int health, int plugType, int level,
4077 int temp, int volt) {
4078 boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
4079 int oldStatus = mHistoryCur.batteryStatus;
4080 if (!mHaveBatteryLevel) {
4081 mHaveBatteryLevel = true;
4082 // We start out assuming that the device is plugged in (not
4083 // on battery). If our first report is now that we are indeed
4084 // plugged in, then twiddle our state to correctly reflect that
4085 // since we won't be going through the full setOnBattery().
4086 if (onBattery == mOnBattery) {
4087 if (onBattery) {
4088 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4089 } else {
4090 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4091 }
4092 }
4093 oldStatus = status;
4094 }
4095 if (onBattery) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004096 mDischargeCurrentLevel = level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004097 mRecordingHistory = true;
4098 }
4099 if (onBattery != mOnBattery) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004100 mHistoryCur.batteryLevel = (byte)level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004101 mHistoryCur.batteryStatus = (byte)status;
4102 mHistoryCur.batteryHealth = (byte)health;
4103 mHistoryCur.batteryPlugType = (byte)plugType;
4104 mHistoryCur.batteryTemperature = (char)temp;
4105 mHistoryCur.batteryVoltage = (char)volt;
4106 setOnBattery(onBattery, oldStatus, level);
4107 } else {
4108 boolean changed = false;
4109 if (mHistoryCur.batteryLevel != level) {
4110 mHistoryCur.batteryLevel = (byte)level;
4111 changed = true;
4112 }
4113 if (mHistoryCur.batteryStatus != status) {
4114 mHistoryCur.batteryStatus = (byte)status;
4115 changed = true;
4116 }
4117 if (mHistoryCur.batteryHealth != health) {
4118 mHistoryCur.batteryHealth = (byte)health;
4119 changed = true;
4120 }
4121 if (mHistoryCur.batteryPlugType != plugType) {
4122 mHistoryCur.batteryPlugType = (byte)plugType;
4123 changed = true;
4124 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08004125 if (temp >= (mHistoryCur.batteryTemperature+10)
4126 || temp <= (mHistoryCur.batteryTemperature-10)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004127 mHistoryCur.batteryTemperature = (char)temp;
4128 changed = true;
4129 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08004130 if (volt > (mHistoryCur.batteryVoltage+20)
4131 || volt < (mHistoryCur.batteryVoltage-20)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004132 mHistoryCur.batteryVoltage = (char)volt;
4133 changed = true;
4134 }
4135 if (changed) {
4136 addHistoryRecordLocked(SystemClock.elapsedRealtime());
4137 }
4138 }
4139 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
4140 // We don't record history while we are plugged in and fully charged.
4141 // The next time we are unplugged, history will be cleared.
4142 mRecordingHistory = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004143 }
Evan Millar633a1742009-04-02 16:36:33 -07004144 }
Evan Millarc64edde2009-04-18 12:26:32 -07004145
4146 public void updateKernelWakelocksLocked() {
4147 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
4148
Marco Nelissend8593312009-04-30 14:45:06 -07004149 if (m == null) {
4150 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004151 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07004152 return;
4153 }
4154
Evan Millarc64edde2009-04-18 12:26:32 -07004155 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
4156 String name = ent.getKey();
4157 KernelWakelockStats kws = ent.getValue();
4158
4159 SamplingTimer kwlt = mKernelWakelockStats.get(name);
4160 if (kwlt == null) {
4161 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
4162 true /* track reported values */);
4163 mKernelWakelockStats.put(name, kwlt);
4164 }
4165 kwlt.updateCurrentReportedCount(kws.mCount);
4166 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
4167 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
4168 }
4169
4170 if (m.size() != mKernelWakelockStats.size()) {
4171 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
4172 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4173 SamplingTimer st = ent.getValue();
4174 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
4175 st.setStale();
4176 }
4177 }
4178 }
4179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004180
4181 public long getAwakeTimeBattery() {
4182 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
4183 }
4184
4185 public long getAwakeTimePlugged() {
4186 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
4187 }
4188
4189 @Override
4190 public long computeUptime(long curTime, int which) {
4191 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004192 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004193 case STATS_LAST: return mLastUptime;
4194 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004195 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004196 }
4197 return 0;
4198 }
4199
4200 @Override
4201 public long computeRealtime(long curTime, int which) {
4202 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004203 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004204 case STATS_LAST: return mLastRealtime;
4205 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004206 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 }
4208 return 0;
4209 }
4210
4211 @Override
4212 public long computeBatteryUptime(long curTime, int which) {
4213 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004214 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004215 return mBatteryUptime + getBatteryUptime(curTime);
4216 case STATS_LAST:
4217 return mBatteryLastUptime;
4218 case STATS_CURRENT:
4219 return getBatteryUptime(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004220 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004221 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
4222 }
4223 return 0;
4224 }
4225
4226 @Override
4227 public long computeBatteryRealtime(long curTime, int which) {
4228 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004229 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004230 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
4231 case STATS_LAST:
4232 return mBatteryLastRealtime;
4233 case STATS_CURRENT:
4234 return getBatteryRealtimeLocked(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004235 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004236 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
4237 }
4238 return 0;
4239 }
4240
4241 long getBatteryUptimeLocked(long curTime) {
4242 long time = mTrackBatteryPastUptime;
4243 if (mOnBatteryInternal) {
4244 time += curTime - mTrackBatteryUptimeStart;
4245 }
4246 return time;
4247 }
4248
4249 long getBatteryUptimeLocked() {
4250 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
4251 }
4252
4253 @Override
4254 public long getBatteryUptime(long curTime) {
4255 return getBatteryUptimeLocked(curTime);
4256 }
4257
4258 long getBatteryRealtimeLocked(long curTime) {
4259 long time = mTrackBatteryPastRealtime;
4260 if (mOnBatteryInternal) {
4261 time += curTime - mTrackBatteryRealtimeStart;
4262 }
4263 return time;
4264 }
4265
4266 @Override
4267 public long getBatteryRealtime(long curTime) {
4268 return getBatteryRealtimeLocked(curTime);
4269 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004270
4271 private long getTcpBytes(long current, long[] dataBytes, int which) {
4272 if (which == STATS_LAST) {
4273 return dataBytes[STATS_LAST];
4274 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004275 if (which == STATS_SINCE_UNPLUGGED) {
4276 if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004277 return dataBytes[STATS_LAST];
4278 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004279 return current - dataBytes[STATS_SINCE_UNPLUGGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004280 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004281 } else if (which == STATS_SINCE_CHARGED) {
4282 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004283 }
4284 return current - dataBytes[STATS_CURRENT];
4285 }
4286 }
4287
4288 /** Only STATS_UNPLUGGED works properly */
4289 public long getMobileTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004290 return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004291 }
4292
4293 /** Only STATS_UNPLUGGED works properly */
4294 public long getMobileTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004295 return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004296 }
4297
4298 /** Only STATS_UNPLUGGED works properly */
4299 public long getTotalTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004300 return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004301 }
4302
4303 /** Only STATS_UNPLUGGED works properly */
4304 public long getTotalTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004305 return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004306 }
4307
The Android Open Source Project10592532009-03-18 17:39:46 -07004308 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004309 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004310 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004311 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004312 }
4313 }
4314
Evan Millar633a1742009-04-02 16:36:33 -07004315 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004316 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004317 }
4318
4319 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004320 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004321 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004322 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004323 }
4324 }
4325
Evan Millar633a1742009-04-02 16:36:33 -07004326 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004327 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004329
Amith Yamasanie43530a2009-08-21 13:11:37 -07004330 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004331 public int getLowDischargeAmountSinceCharge() {
4332 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004333 int val = mLowDischargeAmountSinceCharge;
4334 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4335 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
4336 }
4337 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004338 }
4339 }
4340
4341 @Override
4342 public int getHighDischargeAmountSinceCharge() {
4343 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004344 int val = mHighDischargeAmountSinceCharge;
4345 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4346 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
4347 }
4348 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004349 }
4350 }
4351
4352 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07004353 public int getCpuSpeedSteps() {
4354 return sNumSpeedSteps;
4355 }
4356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004357 /**
4358 * Retrieve the statistics object for a particular uid, creating if needed.
4359 */
4360 public Uid getUidStatsLocked(int uid) {
4361 Uid u = mUidStats.get(uid);
4362 if (u == null) {
4363 u = new Uid(uid);
4364 mUidStats.put(uid, u);
4365 }
4366 return u;
4367 }
4368
4369 /**
4370 * Remove the statistics object for a particular uid.
4371 */
4372 public void removeUidStatsLocked(int uid) {
4373 mUidStats.remove(uid);
4374 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004376 /**
4377 * Retrieve the statistics object for a particular process, creating
4378 * if needed.
4379 */
4380 public Uid.Proc getProcessStatsLocked(int uid, String name) {
4381 Uid u = getUidStatsLocked(uid);
4382 return u.getProcessStatsLocked(name);
4383 }
4384
4385 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004386 * Retrieve the statistics object for a particular process, given
4387 * the name of the process.
4388 * @param name process name
4389 * @return the statistics object for the process
4390 */
Amith Yamasani819f9282009-06-24 23:18:15 -07004391 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004392 int uid;
4393 if (mUidCache.containsKey(name)) {
4394 uid = mUidCache.get(name);
4395 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07004396 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004397 mUidCache.put(name, uid);
4398 }
4399 Uid u = getUidStatsLocked(uid);
4400 return u.getProcessStatsLocked(name);
4401 }
4402
4403 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 * Retrieve the statistics object for a particular process, creating
4405 * if needed.
4406 */
4407 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
4408 Uid u = getUidStatsLocked(uid);
4409 return u.getPackageStatsLocked(pkg);
4410 }
4411
4412 /**
4413 * Retrieve the statistics object for a particular service, creating
4414 * if needed.
4415 */
4416 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
4417 Uid u = getUidStatsLocked(uid);
4418 return u.getServiceStatsLocked(pkg, name);
4419 }
4420
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004421 /**
4422 * Massage data to distribute any reasonable work down to more specific
4423 * owners. Must only be called on a dead BatteryStats object!
4424 */
4425 public void distributeWorkLocked(int which) {
4426 // Aggregate all CPU time associated with WIFI.
4427 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
4428 if (wifiUid != null) {
4429 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
4430 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
4431 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
4432 for (int i=0; i<mUidStats.size(); i++) {
4433 Uid uid = mUidStats.valueAt(i);
4434 if (uid.mUid != Process.WIFI_UID) {
4435 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
4436 if (uidRunningTime > 0) {
4437 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
4438 long time = proc.getUserTime(which);
4439 time = (time*uidRunningTime)/totalRunningTime;
4440 uidProc.mUserTime += time;
4441 proc.mUserTime -= time;
4442 time = proc.getSystemTime(which);
4443 time = (time*uidRunningTime)/totalRunningTime;
4444 uidProc.mSystemTime += time;
4445 proc.mSystemTime -= time;
4446 time = proc.getForegroundTime(which);
4447 time = (time*uidRunningTime)/totalRunningTime;
4448 uidProc.mForegroundTime += time;
4449 proc.mForegroundTime -= time;
4450 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
4451 SamplingCounter sc = proc.mSpeedBins[sb];
4452 if (sc != null) {
4453 time = sc.getCountLocked(which);
4454 time = (time*uidRunningTime)/totalRunningTime;
4455 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
4456 if (uidSc == null) {
4457 uidSc = new SamplingCounter(mUnpluggables);
4458 uidProc.mSpeedBins[sb] = uidSc;
4459 }
4460 uidSc.mCount.addAndGet((int)time);
4461 sc.mCount.addAndGet((int)-time);
4462 }
4463 }
4464 totalRunningTime -= uidRunningTime;
4465 }
4466 }
4467 }
4468 }
4469 }
4470 }
4471
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004472 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004473 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004474 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004475 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004476
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004477 Parcel mPendingWrite = null;
4478 final ReentrantLock mWriteLock = new ReentrantLock();
4479
4480 public void writeAsyncLocked() {
4481 writeLocked(false);
4482 }
4483
4484 public void writeSyncLocked() {
4485 writeLocked(true);
4486 }
4487
4488 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004489 if (mFile == null) {
4490 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 return;
4492 }
4493
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004494 if (mShuttingDown) {
4495 return;
4496 }
4497
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004498 Parcel out = Parcel.obtain();
4499 writeSummaryToParcel(out);
4500 mLastWriteTime = SystemClock.elapsedRealtime();
4501
4502 if (mPendingWrite != null) {
4503 mPendingWrite.recycle();
4504 }
4505 mPendingWrite = out;
4506
4507 if (sync) {
4508 commitPendingDataToDisk();
4509 } else {
4510 Thread thr = new Thread("BatteryStats-Write") {
4511 @Override
4512 public void run() {
4513 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
4514 commitPendingDataToDisk();
4515 }
4516 };
4517 thr.start();
4518 }
4519 }
4520
4521 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004522 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004523 synchronized (this) {
4524 next = mPendingWrite;
4525 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004526 if (next == null) {
4527 return;
4528 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004529
4530 mWriteLock.lock();
4531 }
4532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004533 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004534 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004535 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07004537 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004538 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004539 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004541 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004542 mFile.rollback();
4543 } finally {
4544 next.recycle();
4545 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07004546 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004547 }
4548
4549 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
4550 int pos = 0;
4551 int avail = stream.available();
4552 byte[] data = new byte[avail];
4553 while (true) {
4554 int amt = stream.read(data, pos, data.length-pos);
4555 //Log.i("foo", "Read " + amt + " bytes at " + pos
4556 // + " of avail " + data.length);
4557 if (amt <= 0) {
4558 //Log.i("foo", "**** FINISHED READING: pos=" + pos
4559 // + " len=" + data.length);
4560 return data;
4561 }
4562 pos += amt;
4563 avail = stream.available();
4564 if (avail > data.length-pos) {
4565 byte[] newData = new byte[pos+avail];
4566 System.arraycopy(data, 0, newData, 0, pos);
4567 data = newData;
4568 }
4569 }
4570 }
4571
4572 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004573 if (mFile == null) {
4574 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004575 return;
4576 }
4577
4578 mUidStats.clear();
4579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004580 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004581 File file = mFile.chooseForRead();
4582 if (!file.exists()) {
4583 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004584 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004585 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004586
4587 byte[] raw = readFully(stream);
4588 Parcel in = Parcel.obtain();
4589 in.unmarshall(raw, 0, raw.length);
4590 in.setDataPosition(0);
4591 stream.close();
4592
4593 readSummaryFromParcel(in);
4594 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004595 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004596 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004597
4598 addHistoryRecordLocked(SystemClock.elapsedRealtime(), HistoryItem.CMD_START);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 }
4600
4601 public int describeContents() {
4602 return 0;
4603 }
4604
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004605 void readHistory(Parcel in) {
4606 mHistory = mHistoryEnd = mHistoryCache = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004607 mHistoryBaseTime = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004608 long time;
4609 while ((time=in.readLong()) >= 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004610 HistoryItem rec = new HistoryItem(time, in);
4611 addHistoryRecordLocked(rec);
4612 if (rec.time > mHistoryBaseTime) {
4613 mHistoryBaseTime = rec.time;
4614 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004615 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07004616
4617 long oldnow = SystemClock.elapsedRealtime() - (5*60*100);
4618 if (oldnow > 0) {
4619 // If the system process has restarted, but not the entire
4620 // system, then the mHistoryBaseTime already accounts for
4621 // much of the elapsed time. We thus want to adjust it back,
4622 // to avoid large gaps in the data. We determine we are
4623 // in this case by arbitrarily saying it is so if at this
4624 // point in boot the elapsed time is already more than 5 seconds.
4625 mHistoryBaseTime -= oldnow;
4626 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004627 }
4628
4629 void writeHistory(Parcel out) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004630 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004631 while (rec != null) {
4632 if (rec.time >= 0) rec.writeToParcel(out, 0);
4633 rec = rec.next;
4634 }
4635 out.writeLong(-1);
4636 }
4637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 private void readSummaryFromParcel(Parcel in) {
4639 final int version = in.readInt();
4640 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004641 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 + ", expected " + VERSION + "; erasing old stats");
4643 return;
4644 }
4645
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004646 readHistory(in);
4647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004648 mStartCount = in.readInt();
4649 mBatteryUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 mBatteryRealtime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004651 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004652 mRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004653 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07004654 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004655 mLowDischargeAmountSinceCharge = in.readInt();
4656 mHighDischargeAmountSinceCharge = in.readInt();
The Android Open Source Project10592532009-03-18 17:39:46 -07004657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 mStartCount++;
4659
4660 mScreenOn = false;
4661 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004662 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4663 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
4664 }
4665 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004666 mPhoneOn = false;
4667 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004668 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
4669 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
4670 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004671 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004672 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4673 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
4674 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004675 mWifiOn = false;
4676 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004677 mGlobalWifiRunning = false;
4678 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07004679 mBluetoothOn = false;
4680 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681
Evan Millarc64edde2009-04-18 12:26:32 -07004682 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004683 if (NKW > 10000) {
4684 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
4685 return;
4686 }
Evan Millarc64edde2009-04-18 12:26:32 -07004687 for (int ikw = 0; ikw < NKW; ikw++) {
4688 if (in.readInt() != 0) {
4689 String kwltName = in.readString();
4690 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
4691 }
4692 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004693
4694 sNumSpeedSteps = in.readInt();
4695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004696 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004697 if (NU > 10000) {
4698 Slog.w(TAG, "File corrupt: too many uids " + NU);
4699 return;
4700 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004701 for (int iu = 0; iu < NU; iu++) {
4702 int uid = in.readInt();
4703 Uid u = new Uid(uid);
4704 mUidStats.put(uid, u);
4705
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004706 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004707 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004708 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004709 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004710 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004711 if (in.readInt() != 0) {
4712 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
4713 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004714 u.mScanWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004715 if (in.readInt() != 0) {
4716 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
4717 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004718 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004719 if (in.readInt() != 0) {
4720 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
4721 }
4722 u.mAudioTurnedOn = false;
4723 if (in.readInt() != 0) {
4724 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
4725 }
4726 u.mVideoTurnedOn = false;
4727 if (in.readInt() != 0) {
4728 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
4729 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004730
Dianne Hackborn617f8772009-03-31 15:04:46 -07004731 if (in.readInt() != 0) {
4732 if (u.mUserActivityCounters == null) {
4733 u.initUserActivityLocked();
4734 }
4735 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
4736 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
4737 }
4738 }
4739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004741 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004742 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
4743 return;
4744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004745 for (int iw = 0; iw < NW; iw++) {
4746 String wlName = in.readString();
4747 if (in.readInt() != 0) {
4748 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
4749 }
4750 if (in.readInt() != 0) {
4751 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
4752 }
4753 if (in.readInt() != 0) {
4754 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
4755 }
4756 }
4757
4758 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004759 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004760 Slog.w(TAG, "File corrupt: too many sensors " + NP);
4761 return;
4762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 for (int is = 0; is < NP; is++) {
4764 int seNumber = in.readInt();
4765 if (in.readInt() != 0) {
4766 u.getSensorTimerLocked(seNumber, true)
4767 .readSummaryFromParcelLocked(in);
4768 }
4769 }
4770
4771 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004772 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004773 Slog.w(TAG, "File corrupt: too many processes " + NP);
4774 return;
4775 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004776 for (int ip = 0; ip < NP; ip++) {
4777 String procName = in.readString();
4778 Uid.Proc p = u.getProcessStatsLocked(procName);
4779 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004780 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004781 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004782 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004783 if (NSB > 100) {
4784 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
4785 return;
4786 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004787 p.mSpeedBins = new SamplingCounter[NSB];
4788 for (int i=0; i<NSB; i++) {
4789 if (in.readInt() != 0) {
4790 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables);
4791 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
4792 }
4793 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004794 if (!p.readExcessivePowerFromParcelLocked(in)) {
4795 return;
4796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004797 }
4798
4799 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004800 if (NP > 10000) {
4801 Slog.w(TAG, "File corrupt: too many packages " + NP);
4802 return;
4803 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004804 for (int ip = 0; ip < NP; ip++) {
4805 String pkgName = in.readString();
4806 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
4807 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004808 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004809 if (NS > 1000) {
4810 Slog.w(TAG, "File corrupt: too many services " + NS);
4811 return;
4812 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004813 for (int is = 0; is < NS; is++) {
4814 String servName = in.readString();
4815 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
4816 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004817 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004818 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004819 }
4820 }
4821
4822 u.mLoadedTcpBytesReceived = in.readLong();
4823 u.mLoadedTcpBytesSent = in.readLong();
4824 }
4825 }
4826
4827 /**
4828 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
4829 * disk. This format does not allow a lossless round-trip.
4830 *
4831 * @param out the Parcel to be written to.
4832 */
4833 public void writeSummaryToParcel(Parcel out) {
4834 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
4835 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
4836 final long NOW = getBatteryUptimeLocked(NOW_SYS);
4837 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
4838
4839 out.writeInt(VERSION);
4840
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004841 writeHistory(out);
4842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004843 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004844 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004845 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004846 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004847 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004848 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07004849 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004850 out.writeInt(getLowDischargeAmountSinceCharge());
4851 out.writeInt(getHighDischargeAmountSinceCharge());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004852
4853 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004854 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4855 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
4856 }
4857 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004858 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004859 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
4860 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
4861 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004862 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004863 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4864 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
4865 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004866 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004867 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07004868 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004869
Evan Millarc64edde2009-04-18 12:26:32 -07004870 out.writeInt(mKernelWakelockStats.size());
4871 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4872 Timer kwlt = ent.getValue();
4873 if (kwlt != null) {
4874 out.writeInt(1);
4875 out.writeString(ent.getKey());
4876 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
4877 } else {
4878 out.writeInt(0);
4879 }
4880 }
4881
Amith Yamasanie43530a2009-08-21 13:11:37 -07004882 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004883 final int NU = mUidStats.size();
4884 out.writeInt(NU);
4885 for (int iu = 0; iu < NU; iu++) {
4886 out.writeInt(mUidStats.keyAt(iu));
4887 Uid u = mUidStats.valueAt(iu);
The Android Open Source Project10592532009-03-18 17:39:46 -07004888
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004889 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004890 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004891 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004892 } else {
4893 out.writeInt(0);
4894 }
4895 if (u.mFullWifiLockTimer != null) {
4896 out.writeInt(1);
4897 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4898 } else {
4899 out.writeInt(0);
4900 }
4901 if (u.mScanWifiLockTimer != null) {
4902 out.writeInt(1);
4903 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4904 } else {
4905 out.writeInt(0);
4906 }
4907 if (u.mWifiMulticastTimer != null) {
4908 out.writeInt(1);
4909 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4910 } else {
4911 out.writeInt(0);
4912 }
4913 if (u.mAudioTurnedOnTimer != null) {
4914 out.writeInt(1);
4915 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4916 } else {
4917 out.writeInt(0);
4918 }
4919 if (u.mVideoTurnedOnTimer != null) {
4920 out.writeInt(1);
4921 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4922 } else {
4923 out.writeInt(0);
4924 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925
Dianne Hackborn617f8772009-03-31 15:04:46 -07004926 if (u.mUserActivityCounters == null) {
4927 out.writeInt(0);
4928 } else {
4929 out.writeInt(1);
4930 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
4931 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
4932 }
4933 }
4934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004935 int NW = u.mWakelockStats.size();
4936 out.writeInt(NW);
4937 if (NW > 0) {
4938 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
4939 : u.mWakelockStats.entrySet()) {
4940 out.writeString(ent.getKey());
4941 Uid.Wakelock wl = ent.getValue();
4942 if (wl.mTimerFull != null) {
4943 out.writeInt(1);
4944 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
4945 } else {
4946 out.writeInt(0);
4947 }
4948 if (wl.mTimerPartial != null) {
4949 out.writeInt(1);
4950 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
4951 } else {
4952 out.writeInt(0);
4953 }
4954 if (wl.mTimerWindow != null) {
4955 out.writeInt(1);
4956 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
4957 } else {
4958 out.writeInt(0);
4959 }
4960 }
4961 }
4962
4963 int NSE = u.mSensorStats.size();
4964 out.writeInt(NSE);
4965 if (NSE > 0) {
4966 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
4967 : u.mSensorStats.entrySet()) {
4968 out.writeInt(ent.getKey());
4969 Uid.Sensor se = ent.getValue();
4970 if (se.mTimer != null) {
4971 out.writeInt(1);
4972 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4973 } else {
4974 out.writeInt(0);
4975 }
4976 }
4977 }
4978
4979 int NP = u.mProcessStats.size();
4980 out.writeInt(NP);
4981 if (NP > 0) {
4982 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
4983 : u.mProcessStats.entrySet()) {
4984 out.writeString(ent.getKey());
4985 Uid.Proc ps = ent.getValue();
4986 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004987 out.writeLong(ps.mSystemTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004988 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004989 final int N = ps.mSpeedBins.length;
4990 out.writeInt(N);
4991 for (int i=0; i<N; i++) {
4992 if (ps.mSpeedBins[i] != null) {
4993 out.writeInt(1);
4994 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
4995 } else {
4996 out.writeInt(0);
4997 }
4998 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07004999 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005000 }
5001 }
5002
5003 NP = u.mPackageStats.size();
5004 out.writeInt(NP);
5005 if (NP > 0) {
5006 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
5007 : u.mPackageStats.entrySet()) {
5008 out.writeString(ent.getKey());
5009 Uid.Pkg ps = ent.getValue();
5010 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005011 final int NS = ps.mServiceStats.size();
5012 out.writeInt(NS);
5013 if (NS > 0) {
5014 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
5015 : ps.mServiceStats.entrySet()) {
5016 out.writeString(sent.getKey());
5017 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
5018 long time = ss.getStartTimeToNowLocked(NOW);
5019 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005020 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005021 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005022 }
5023 }
5024 }
5025 }
5026
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005027 out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED));
5028 out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005029 }
5030 }
5031
5032 public void readFromParcel(Parcel in) {
5033 readFromParcelLocked(in);
5034 }
5035
5036 void readFromParcelLocked(Parcel in) {
5037 int magic = in.readInt();
5038 if (magic != MAGIC) {
5039 throw new ParcelFormatException("Bad magic number");
5040 }
5041
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005042 readHistory(in);
5043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005044 mStartCount = in.readInt();
5045 mBatteryUptime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005046 mBatteryLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005047 mBatteryRealtime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005048 mBatteryLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005049 mScreenOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005050 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005051 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005052 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i,
5053 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005054 }
5055 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005056 mPhoneOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005057 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005058 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005059 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
5060 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005061 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005062 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005063 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005064 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
5065 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005066 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005067 mWifiOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005068 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005069 mGlobalWifiRunning = false;
5070 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005071 mBluetoothOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005072 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005073 mUptime = in.readLong();
5074 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005075 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005076 mRealtime = in.readLong();
5077 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005078 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005079 mOnBattery = in.readInt() != 0;
5080 mOnBatteryInternal = false; // we are no longer really running.
5081 mTrackBatteryPastUptime = in.readLong();
5082 mTrackBatteryUptimeStart = in.readLong();
5083 mTrackBatteryPastRealtime = in.readLong();
5084 mTrackBatteryRealtimeStart = in.readLong();
5085 mUnpluggedBatteryUptime = in.readLong();
5086 mUnpluggedBatteryRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005087 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005088 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005089 mLowDischargeAmountSinceCharge = in.readInt();
5090 mHighDischargeAmountSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005091 mLastWriteTime = in.readLong();
5092
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005093 mMobileDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005094 mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005095 mMobileDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005096 mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005097 mTotalDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005098 mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005099 mTotalDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005100 mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005101
5102 mRadioDataUptime = in.readLong();
5103 mRadioDataStart = -1;
5104
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005105 mBluetoothPingCount = in.readInt();
5106 mBluetoothPingStart = -1;
5107
Evan Millarc64edde2009-04-18 12:26:32 -07005108 mKernelWakelockStats.clear();
5109 int NKW = in.readInt();
5110 for (int ikw = 0; ikw < NKW; ikw++) {
5111 if (in.readInt() != 0) {
5112 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005113 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07005114 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
5115 mKernelWakelockStats.put(wakelockName, kwlt);
5116 }
5117 }
5118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005119 mPartialTimers.clear();
5120 mFullTimers.clear();
5121 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005122 mWifiRunningTimers.clear();
5123 mFullWifiLockTimers.clear();
5124 mScanWifiLockTimers.clear();
5125 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126
Amith Yamasanie43530a2009-08-21 13:11:37 -07005127 sNumSpeedSteps = in.readInt();
5128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005129 int numUids = in.readInt();
5130 mUidStats.clear();
5131 for (int i = 0; i < numUids; i++) {
5132 int uid = in.readInt();
5133 Uid u = new Uid(uid);
5134 u.readFromParcelLocked(mUnpluggables, in);
5135 mUidStats.append(uid, u);
5136 }
5137 }
5138
5139 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005140 writeToParcelLocked(out, true, flags);
5141 }
5142
5143 public void writeToParcelWithoutUids(Parcel out, int flags) {
5144 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005145 }
5146
5147 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005148 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005149 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
5150 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
5151 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
5152 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
5153
5154 out.writeInt(MAGIC);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005155
5156 writeHistory(out);
5157
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005158 out.writeInt(mStartCount);
5159 out.writeLong(mBatteryUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005160 out.writeLong(mBatteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005161 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005162 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5163 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
5164 }
5165 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005166 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005167 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
5168 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
5169 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005170 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005171 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5172 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
5173 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005174 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005175 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005176 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005177 out.writeLong(mUptime);
5178 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005179 out.writeLong(mRealtime);
5180 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 out.writeInt(mOnBattery ? 1 : 0);
5182 out.writeLong(batteryUptime);
5183 out.writeLong(mTrackBatteryUptimeStart);
5184 out.writeLong(batteryRealtime);
5185 out.writeLong(mTrackBatteryRealtimeStart);
5186 out.writeLong(mUnpluggedBatteryUptime);
5187 out.writeLong(mUnpluggedBatteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005188 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005189 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005190 out.writeInt(mLowDischargeAmountSinceCharge);
5191 out.writeInt(mHighDischargeAmountSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005192 out.writeLong(mLastWriteTime);
5193
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005194 out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5195 out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED));
5196 out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5197 out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED));
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005198
5199 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005200 out.writeLong(getRadioDataUptime());
5201
5202 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005203
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005204 if (inclUids) {
5205 out.writeInt(mKernelWakelockStats.size());
5206 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5207 SamplingTimer kwlt = ent.getValue();
5208 if (kwlt != null) {
5209 out.writeInt(1);
5210 out.writeString(ent.getKey());
5211 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
5212 } else {
5213 out.writeInt(0);
5214 }
Evan Millarc64edde2009-04-18 12:26:32 -07005215 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005216 } else {
5217 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07005218 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005219
5220 out.writeInt(sNumSpeedSteps);
5221
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005222 if (inclUids) {
5223 int size = mUidStats.size();
5224 out.writeInt(size);
5225 for (int i = 0; i < size; i++) {
5226 out.writeInt(mUidStats.keyAt(i));
5227 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005228
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005229 uid.writeToParcelLocked(out, batteryRealtime);
5230 }
5231 } else {
5232 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 }
5234 }
5235
5236 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
5237 new Parcelable.Creator<BatteryStatsImpl>() {
5238 public BatteryStatsImpl createFromParcel(Parcel in) {
5239 return new BatteryStatsImpl(in);
5240 }
5241
5242 public BatteryStatsImpl[] newArray(int size) {
5243 return new BatteryStatsImpl[size];
5244 }
5245 };
5246
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005247 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005248 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005249 Printer pr = new PrintWriterPrinter(pw);
5250 pr.println("*** Screen timer:");
5251 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005252 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005253 pr.println("*** Screen brightness #" + i + ":");
5254 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005255 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005256 pr.println("*** Input event counter:");
5257 mInputEventCounter.logState(pr, " ");
5258 pr.println("*** Phone timer:");
5259 mPhoneOnTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005260 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005261 pr.println("*** Signal strength #" + i + ":");
5262 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005263 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005264 pr.println("*** Signal scanning :");
5265 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005266 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005267 pr.println("*** Data connection type #" + i + ":");
5268 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005269 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005270 pr.println("*** Wifi timer:");
5271 mWifiOnTimer.logState(pr, " ");
5272 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005273 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005274 pr.println("*** Bluetooth timer:");
5275 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 }
5277 super.dumpLocked(pw);
5278 }
5279}