blob: 24275ec4ac31d5fb7a804eb6007dc38c65ff3d43 [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.os.BatteryStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.os.Parcel;
25import android.os.ParcelFormatException;
26import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070027import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.os.SystemClock;
Amith Yamasanif37447b2009-10-08 18:28:01 -070029import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070030import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070031import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.util.Log;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070033import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070035import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.util.SparseArray;
37
Amith Yamasani3718aaa2009-06-09 06:32:35 -070038import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import java.io.File;
40import java.io.FileInputStream;
41import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070042import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070044import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import java.util.ArrayList;
46import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070047import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070049import java.util.concurrent.atomic.AtomicInteger;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050
51/**
52 * All information we are collecting about things that can happen that impact
53 * battery life. All times are represented in microseconds except where indicated
54 * otherwise.
55 */
56public final class BatteryStatsImpl extends BatteryStats {
57 private static final String TAG = "BatteryStatsImpl";
58 private static final boolean DEBUG = false;
59
60 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
61 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
62
63 // Current on-disk Parcel version
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070064 private static final int VERSION = 43;
Amith Yamasanie43530a2009-08-21 13:11:37 -070065
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080066 // The maximum number of names wakelocks we will keep track of
67 // per uid; once the limit is reached, we batch the remaining wakelocks
68 // in to one common name.
69 private static final int MAX_WAKELOCKS_PER_UID = 20;
70
71 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
72
Amith Yamasanie43530a2009-08-21 13:11:37 -070073 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070075 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
77 /**
78 * The statistics we have collected organized by uids.
79 */
80 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
81 new SparseArray<BatteryStatsImpl.Uid>();
82
83 // A set of pools of currently active timers. When a timer is queried, we will divide the
84 // elapsed time by the number of active timers to arrive at that timer's share of the time.
85 // In order to do this, we must refresh each timer whenever the number of active timers
86 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -070087 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
88 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
89 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
90 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
91 = new SparseArray<ArrayList<StopwatchTimer>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092
93 // These are the objects that will want to do something when the device
94 // is unplugged from power.
95 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
96
97 int mStartCount;
98
99 long mBatteryUptime;
100 long mBatteryLastUptime;
101 long mBatteryRealtime;
102 long mBatteryLastRealtime;
103
104 long mUptime;
105 long mUptimeStart;
106 long mLastUptime;
107 long mRealtime;
108 long mRealtimeStart;
109 long mLastRealtime;
110
111 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700112 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700113
Dianne Hackborn617f8772009-03-31 15:04:46 -0700114 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700115 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Dianne Hackborn617f8772009-03-31 15:04:46 -0700116
117 Counter mInputEventCounter;
118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700120 StopwatchTimer mPhoneOnTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700122 boolean mAudioOn;
123 StopwatchTimer mAudioOnTimer;
124
125 boolean mVideoOn;
126 StopwatchTimer mVideoOnTimer;
127
Dianne Hackborn627bba72009-03-24 22:32:56 -0700128 int mPhoneSignalStrengthBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700129 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
130 new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700131
132 StopwatchTimer mPhoneSignalScanningTimer;
133
Dianne Hackborn627bba72009-03-24 22:32:56 -0700134 int mPhoneDataConnectionType = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700135 final StopwatchTimer[] mPhoneDataConnectionsTimer =
136 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700137
The Android Open Source Project10592532009-03-18 17:39:46 -0700138 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700139 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700140 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700141
142 boolean mWifiRunning;
Evan Millarc64edde2009-04-18 12:26:32 -0700143 StopwatchTimer mWifiRunningTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -0700144
145 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700146 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700147
148 /** Bluetooth headset object */
149 BluetoothHeadset mBtHeadset;
150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 /**
152 * These provide time bases that discount the time the device is plugged
153 * in to power.
154 */
155 boolean mOnBattery;
156 boolean mOnBatteryInternal;
157 long mTrackBatteryPastUptime;
158 long mTrackBatteryUptimeStart;
159 long mTrackBatteryPastRealtime;
160 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 long mUnpluggedBatteryUptime;
163 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700164
The Android Open Source Project10592532009-03-18 17:39:46 -0700165 /*
166 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
167 */
Evan Millar633a1742009-04-02 16:36:33 -0700168 int mDischargeStartLevel;
169 int mDischargeCurrentLevel;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700172
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700173 // Mobile data transferred while on battery
174 private long[] mMobileDataTx = new long[4];
175 private long[] mMobileDataRx = new long[4];
176 private long[] mTotalDataTx = new long[4];
177 private long[] mTotalDataRx = new long[4];
178
179 private long mRadioDataUptime;
180 private long mRadioDataStart;
181
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700182 private int mBluetoothPingCount;
183 private int mBluetoothPingStart = -1;
184
Amith Yamasanif37447b2009-10-08 18:28:01 -0700185 private int mPhoneServiceState = -1;
186
Evan Millarc64edde2009-04-18 12:26:32 -0700187 /*
188 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
189 */
190 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
191 new HashMap<String, SamplingTimer>();
192
193 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
194 return mKernelWakelockStats;
195 }
196
197 private static int sKernelWakelockUpdateVersion = 0;
198
199 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
200 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
201 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
202 Process.PROC_TAB_TERM,
203 Process.PROC_TAB_TERM,
204 Process.PROC_TAB_TERM,
205 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
206 };
207
208 private final String[] mProcWakelocksName = new String[3];
209 private final long[] mProcWakelocksData = new long[3];
210
211 /*
212 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
213 * to mKernelWakelockStats.
214 */
215 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
216 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700218 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 // For debugging
221 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700222 mFile = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 }
224
225 public static interface Unpluggable {
226 void unplug(long batteryUptime, long batteryRealtime);
227 void plug(long batteryUptime, long batteryRealtime);
228 }
229
230 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700231 * State for keeping track of counting information.
232 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700233 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700234 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700235 int mLoadedCount;
236 int mLastCount;
237 int mUnpluggedCount;
238 int mPluggedCount;
239
240 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700241 mPluggedCount = in.readInt();
242 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700243 mLoadedCount = in.readInt();
244 mLastCount = in.readInt();
245 mUnpluggedCount = in.readInt();
246 unpluggables.add(this);
247 }
248
249 Counter(ArrayList<Unpluggable> unpluggables) {
250 unpluggables.add(this);
251 }
252
253 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700254 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700255 out.writeInt(mLoadedCount);
256 out.writeInt(mLastCount);
257 out.writeInt(mUnpluggedCount);
258 }
259
260 public void unplug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700261 mUnpluggedCount = mPluggedCount;
262 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700263 }
264
265 public void plug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700266 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700267 }
268
269 /**
270 * Writes a possibly null Counter to a Parcel.
271 *
272 * @param out the Parcel to be written to.
273 * @param counter a Counter, or null.
274 */
275 public static void writeCounterToParcel(Parcel out, Counter counter) {
276 if (counter == null) {
277 out.writeInt(0); // indicates null
278 return;
279 }
280 out.writeInt(1); // indicates non-null
281
282 counter.writeToParcel(out);
283 }
284
285 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700286 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700287 int val;
288 if (which == STATS_LAST) {
289 val = mLastCount;
290 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700291 val = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700292 if (which == STATS_UNPLUGGED) {
293 val -= mUnpluggedCount;
294 } else if (which != STATS_TOTAL) {
295 val -= mLoadedCount;
296 }
297 }
298
299 return val;
300 }
301
302 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700303 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700304 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
305 + " mUnpluggedCount=" + mUnpluggedCount
306 + " mPluggedCount=" + mPluggedCount);
307 }
308
Christopher Tate4cee7252010-03-19 14:50:40 -0700309 void stepAtomic() {
310 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700311 }
312
313 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700314 int count = mCount.get();
315 out.writeInt(count);
316 out.writeInt(count - mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700317 }
318
319 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700320 mLoadedCount = in.readInt();
321 mCount.set(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700322 mLastCount = in.readInt();
Christopher Tate4cee7252010-03-19 14:50:40 -0700323 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700324 }
325 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700326
327 public static class SamplingCounter extends Counter {
328
329 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
330 super(unpluggables, in);
331 }
332
333 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
334 super(unpluggables);
335 }
336
Christopher Tate4cee7252010-03-19 14:50:40 -0700337 public void addCountAtomic(long count) {
338 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700339 }
340 }
341
Dianne Hackborn617f8772009-03-31 15:04:46 -0700342 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 * State for keeping track of timing information.
344 */
Evan Millarc64edde2009-04-18 12:26:32 -0700345 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 final int mType;
Evan Millarc64edde2009-04-18 12:26:32 -0700347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348
349 int mCount;
350 int mLoadedCount;
351 int mLastCount;
352 int mUnpluggedCount;
353
354 // Times are in microseconds for better accuracy when dividing by the
355 // lock count, and are in "battery realtime" units.
356
357 /**
358 * The total time we have accumulated since the start of the original
359 * boot, to the last time something interesting happened in the
360 * current run.
361 */
362 long mTotalTime;
363
364 /**
365 * The total time we loaded for the previous runs. Subtract this from
366 * mTotalTime to find the time for the current run of the system.
367 */
368 long mLoadedTime;
369
370 /**
371 * The run time of the last run of the system, as loaded from the
372 * saved data.
373 */
374 long mLastTime;
375
376 /**
377 * The value of mTotalTime when unplug() was last called. Subtract
378 * this from mTotalTime to find the time since the last unplug from
379 * power.
380 */
381 long mUnpluggedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700383 /**
384 * Constructs from a parcel.
385 * @param type
386 * @param unpluggables
387 * @param powerType
388 * @param in
389 */
Evan Millarc64edde2009-04-18 12:26:32 -0700390 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 mType = type;
Evan Millarc64edde2009-04-18 12:26:32 -0700392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 mCount = in.readInt();
394 mLoadedCount = in.readInt();
395 mLastCount = in.readInt();
396 mUnpluggedCount = in.readInt();
397 mTotalTime = in.readLong();
398 mLoadedTime = in.readLong();
399 mLastTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 mUnpluggedTime = in.readLong();
401 unpluggables.add(this);
402 }
403
Evan Millarc64edde2009-04-18 12:26:32 -0700404 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 mType = type;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 unpluggables.add(this);
407 }
Evan Millarc64edde2009-04-18 12:26:32 -0700408
409 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
410
411 protected abstract int computeCurrentCountLocked();
412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413
414 public void writeToParcel(Parcel out, long batteryRealtime) {
415 out.writeInt(mCount);
416 out.writeInt(mLoadedCount);
417 out.writeInt(mLastCount);
418 out.writeInt(mUnpluggedCount);
419 out.writeLong(computeRunTimeLocked(batteryRealtime));
420 out.writeLong(mLoadedTime);
421 out.writeLong(mLastTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 out.writeLong(mUnpluggedTime);
423 }
424
425 public void unplug(long batteryUptime, long batteryRealtime) {
426 if (DEBUG && mType < 0) {
427 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
428 + " old mUnpluggedTime=" + mUnpluggedTime
429 + " old mUnpluggedCount=" + mUnpluggedCount);
430 }
431 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
432 mUnpluggedCount = mCount;
433 if (DEBUG && mType < 0) {
434 Log.v(TAG, "unplug #" + mType
435 + ": new mUnpluggedTime=" + mUnpluggedTime
436 + " new mUnpluggedCount=" + mUnpluggedCount);
437 }
438 }
439
440 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700441 if (DEBUG && mType < 0) {
442 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
443 + " old mTotalTime=" + mTotalTime);
444 }
445 mTotalTime = computeRunTimeLocked(batteryRealtime);
446 mCount = computeCurrentCountLocked();
447 if (DEBUG && mType < 0) {
448 Log.v(TAG, "plug #" + mType
449 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 }
451 }
452
453 /**
454 * Writes a possibly null Timer to a Parcel.
455 *
456 * @param out the Parcel to be written to.
457 * @param timer a Timer, or null.
458 */
459 public static void writeTimerToParcel(Parcel out, Timer timer,
460 long batteryRealtime) {
461 if (timer == null) {
462 out.writeInt(0); // indicates null
463 return;
464 }
465 out.writeInt(1); // indicates non-null
466
467 timer.writeToParcel(out, batteryRealtime);
468 }
469
470 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700471 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 long val;
473 if (which == STATS_LAST) {
474 val = mLastTime;
475 } else {
476 val = computeRunTimeLocked(batteryRealtime);
477 if (which == STATS_UNPLUGGED) {
478 val -= mUnpluggedTime;
479 } else if (which != STATS_TOTAL) {
480 val -= mLoadedTime;
481 }
482 }
483
484 return val;
485 }
486
487 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700488 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 int val;
490 if (which == STATS_LAST) {
491 val = mLastCount;
492 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700493 val = computeCurrentCountLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 if (which == STATS_UNPLUGGED) {
495 val -= mUnpluggedCount;
496 } else if (which != STATS_TOTAL) {
497 val -= mLoadedCount;
498 }
499 }
500
501 return val;
502 }
503
Dianne Hackborn627bba72009-03-24 22:32:56 -0700504 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700505 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
507 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700508 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700510 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700512 }
513
514
515 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
516 long runTime = computeRunTimeLocked(batteryRealtime);
517 // Divide by 1000 for backwards compatibility
518 out.writeLong((runTime + 500) / 1000);
519 out.writeLong(((runTime - mLoadedTime) + 500) / 1000);
520 out.writeInt(mCount);
521 out.writeInt(mCount - mLoadedCount);
522 }
523
524 void readSummaryFromParcelLocked(Parcel in) {
525 // Multiply by 1000 for backwards compatibility
526 mTotalTime = mLoadedTime = in.readLong() * 1000;
527 mLastTime = in.readLong() * 1000;
528 mUnpluggedTime = mTotalTime;
529 mCount = mLoadedCount = in.readInt();
530 mLastCount = in.readInt();
531 mUnpluggedCount = mCount;
532 }
533 }
534
535 public static final class SamplingTimer extends Timer {
536
537 /**
538 * The most recent reported count from /proc/wakelocks.
539 */
540 int mCurrentReportedCount;
541
542 /**
543 * The reported count from /proc/wakelocks when unplug() was last
544 * called.
545 */
546 int mUnpluggedReportedCount;
547
548 /**
549 * The most recent reported total_time from /proc/wakelocks.
550 */
551 long mCurrentReportedTotalTime;
552
553
554 /**
555 * The reported total_time from /proc/wakelocks when unplug() was last
556 * called.
557 */
558 long mUnpluggedReportedTotalTime;
559
560 /**
561 * Whether we are currently in a discharge cycle.
562 */
563 boolean mInDischarge;
564
565 /**
566 * Whether we are currently recording reported values.
567 */
568 boolean mTrackingReportedValues;
569
570 /*
571 * A sequnce counter, incremented once for each update of the stats.
572 */
573 int mUpdateVersion;
574
575 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
576 super(0, unpluggables, in);
577 mCurrentReportedCount = in.readInt();
578 mUnpluggedReportedCount = in.readInt();
579 mCurrentReportedTotalTime = in.readLong();
580 mUnpluggedReportedTotalTime = in.readLong();
581 mTrackingReportedValues = in.readInt() == 1;
582 mInDischarge = inDischarge;
583 }
584
585 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
586 boolean trackReportedValues) {
587 super(0, unpluggables);
588 mTrackingReportedValues = trackReportedValues;
589 mInDischarge = inDischarge;
590 }
591
592 public void setStale() {
593 mTrackingReportedValues = false;
594 mUnpluggedReportedTotalTime = 0;
595 mUnpluggedReportedCount = 0;
596 }
597
598 public void setUpdateVersion(int version) {
599 mUpdateVersion = version;
600 }
601
602 public int getUpdateVersion() {
603 return mUpdateVersion;
604 }
605
606 public void updateCurrentReportedCount(int count) {
607 if (mInDischarge && mUnpluggedReportedCount == 0) {
608 // Updating the reported value for the first time.
609 mUnpluggedReportedCount = count;
610 // If we are receiving an update update mTrackingReportedValues;
611 mTrackingReportedValues = true;
612 }
613 mCurrentReportedCount = count;
614 }
615
616 public void updateCurrentReportedTotalTime(long totalTime) {
617 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
618 // Updating the reported value for the first time.
619 mUnpluggedReportedTotalTime = totalTime;
620 // If we are receiving an update update mTrackingReportedValues;
621 mTrackingReportedValues = true;
622 }
623 mCurrentReportedTotalTime = totalTime;
624 }
625
626 public void unplug(long batteryUptime, long batteryRealtime) {
627 super.unplug(batteryUptime, batteryRealtime);
628 if (mTrackingReportedValues) {
629 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
630 mUnpluggedReportedCount = mCurrentReportedCount;
631 }
632 mInDischarge = true;
633 }
634
635 public void plug(long batteryUptime, long batteryRealtime) {
636 super.plug(batteryUptime, batteryRealtime);
637 mInDischarge = false;
638 }
639
640 public void logState(Printer pw, String prefix) {
641 super.logState(pw, prefix);
642 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
643 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
644 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
645 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
646 }
647
648 protected long computeRunTimeLocked(long curBatteryRealtime) {
649 return mTotalTime + (mInDischarge && mTrackingReportedValues
650 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
651 }
652
653 protected int computeCurrentCountLocked() {
654 return mCount + (mInDischarge && mTrackingReportedValues
655 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
656 }
657
658 public void writeToParcel(Parcel out, long batteryRealtime) {
659 super.writeToParcel(out, batteryRealtime);
660 out.writeInt(mCurrentReportedCount);
661 out.writeInt(mUnpluggedReportedCount);
662 out.writeLong(mCurrentReportedTotalTime);
663 out.writeLong(mUnpluggedReportedTotalTime);
664 out.writeInt(mTrackingReportedValues ? 1 : 0);
665 }
666
667 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
668 super.writeSummaryFromParcelLocked(out, batteryRealtime);
669 out.writeLong(mCurrentReportedTotalTime);
670 out.writeInt(mCurrentReportedCount);
671 out.writeInt(mTrackingReportedValues ? 1 : 0);
672 }
673
674 void readSummaryFromParcelLocked(Parcel in) {
675 super.readSummaryFromParcelLocked(in);
676 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
677 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
678 mTrackingReportedValues = in.readInt() == 1;
679 }
680 }
681
682 /**
683 * State for keeping track of timing information.
684 */
685 public static final class StopwatchTimer extends Timer {
686 final ArrayList<StopwatchTimer> mTimerPool;
687 int mNesting;
688
689
690 /**
691 * The last time at which we updated the timer. If mNesting is > 0,
692 * subtract this from the current battery time to find the amount of
693 * time we have been running since we last computed an update.
694 */
695 long mUpdateTime;
696
697 /**
698 * The total time at which the timer was acquired, to determine if
699 * was actually held for an interesting duration.
700 */
701 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700702
Amith Yamasanif37447b2009-10-08 18:28:01 -0700703 long mTimeout;
704
Evan Millarc64edde2009-04-18 12:26:32 -0700705 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
706 ArrayList<Unpluggable> unpluggables, Parcel in) {
707 super(type, unpluggables, in);
708 mTimerPool = timerPool;
709 mUpdateTime = in.readLong();
710 }
711
712 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
713 ArrayList<Unpluggable> unpluggables) {
714 super(type, unpluggables);
715 mTimerPool = timerPool;
716 }
717
Amith Yamasanif37447b2009-10-08 18:28:01 -0700718 void setTimeout(long timeout) {
719 mTimeout = timeout;
720 }
721
Evan Millarc64edde2009-04-18 12:26:32 -0700722 public void writeToParcel(Parcel out, long batteryRealtime) {
723 super.writeToParcel(out, batteryRealtime);
724 out.writeLong(mUpdateTime);
725 }
726
727 public void plug(long batteryUptime, long batteryRealtime) {
728 if (mNesting > 0) {
729 if (DEBUG && mType < 0) {
730 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
731 }
732 super.plug(batteryUptime, batteryRealtime);
733 mUpdateTime = batteryRealtime;
734 if (DEBUG && mType < 0) {
735 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
736 }
737 }
738 }
739
740 public void logState(Printer pw, String prefix) {
741 super.logState(pw, prefix);
742 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 + " mAcquireTime=" + mAcquireTime);
744 }
745
746 void startRunningLocked(BatteryStatsImpl stats) {
747 if (mNesting++ == 0) {
748 mUpdateTime = stats.getBatteryRealtimeLocked(
749 SystemClock.elapsedRealtime() * 1000);
750 if (mTimerPool != null) {
751 // Accumulate time to all currently active timers before adding
752 // this new one to the pool.
753 refreshTimersLocked(stats, mTimerPool);
754 // Add this timer to the active pool
755 mTimerPool.add(this);
756 }
757 // Increment the count
758 mCount++;
759 mAcquireTime = mTotalTime;
760 if (DEBUG && mType < 0) {
761 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
762 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
763 + " mAcquireTime=" + mAcquireTime);
764 }
765 }
766 }
767
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700768 boolean isRunningLocked() {
769 return mNesting > 0;
770 }
771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 void stopRunningLocked(BatteryStatsImpl stats) {
773 // Ignore attempt to stop a timer that isn't running
774 if (mNesting == 0) {
775 return;
776 }
777 if (--mNesting == 0) {
778 if (mTimerPool != null) {
779 // Accumulate time to all active counters, scaled by the total
780 // active in the pool, before taking this one out of the pool.
781 refreshTimersLocked(stats, mTimerPool);
782 // Remove this timer from the active pool
783 mTimerPool.remove(this);
784 } else {
785 final long realtime = SystemClock.elapsedRealtime() * 1000;
786 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
787 mNesting = 1;
788 mTotalTime = computeRunTimeLocked(batteryRealtime);
789 mNesting = 0;
790 }
791
792 if (DEBUG && mType < 0) {
793 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
794 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
795 + " mAcquireTime=" + mAcquireTime);
796 }
797
798 if (mTotalTime == mAcquireTime) {
799 // If there was no change in the time, then discard this
800 // count. A somewhat cheezy strategy, but hey.
801 mCount--;
802 }
803 }
804 }
805
806 // Update the total time for all other running Timers with the same type as this Timer
807 // due to a change in timer count
808 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700809 final ArrayList<StopwatchTimer> pool) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 final long realtime = SystemClock.elapsedRealtime() * 1000;
811 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
812 final int N = pool.size();
813 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700814 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 long heldTime = batteryRealtime - t.mUpdateTime;
816 if (heldTime > 0) {
817 t.mTotalTime += heldTime / N;
818 }
819 t.mUpdateTime = batteryRealtime;
820 }
821 }
822
Evan Millarc64edde2009-04-18 12:26:32 -0700823 @Override
824 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700825 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
826 curBatteryRealtime = mUpdateTime + mTimeout;
827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828 return mTotalTime + (mNesting > 0
829 ? (curBatteryRealtime - mUpdateTime)
830 / (mTimerPool != null ? mTimerPool.size() : 1)
831 : 0);
832 }
833
Evan Millarc64edde2009-04-18 12:26:32 -0700834 @Override
835 protected int computeCurrentCountLocked() {
836 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 }
838
839 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -0700840 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 mNesting = 0;
842 }
843 }
844
Evan Millarc64edde2009-04-18 12:26:32 -0700845 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
846
847 byte[] buffer = new byte[4096];
848 int len;
849
850 try {
851 FileInputStream is = new FileInputStream("/proc/wakelocks");
852 len = is.read(buffer);
853 is.close();
854
855 if (len > 0) {
856 int i;
857 for (i=0; i<len; i++) {
858 if (buffer[i] == '\0') {
859 len = i;
860 break;
861 }
862 }
863 }
864 } catch (java.io.FileNotFoundException e) {
865 return null;
866 } catch (java.io.IOException e) {
867 return null;
868 }
869
870 return parseProcWakelocks(buffer, len);
871 }
872
873 private final Map<String, KernelWakelockStats> parseProcWakelocks(
874 byte[] wlBuffer, int len) {
875 String name;
876 int count;
877 long totalTime;
878 int startIndex, endIndex;
879 int numUpdatedWlNames = 0;
880
881 // Advance past the first line.
882 int i;
883 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
884 startIndex = endIndex = i + 1;
885
886 synchronized(this) {
887 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
888
889 sKernelWakelockUpdateVersion++;
890 while (endIndex < len) {
891 for (endIndex=startIndex;
892 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
893 endIndex++);
894 endIndex++; // endIndex is an exclusive upper bound.
895
896 String[] nameStringArray = mProcWakelocksName;
897 long[] wlData = mProcWakelocksData;
Amith Yamasani53b707b2009-09-30 11:05:30 -0700898 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
899 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null);
Evan Millarc64edde2009-04-18 12:26:32 -0700900
901 name = nameStringArray[0];
902 count = (int) wlData[1];
903 // convert nanoseconds to microseconds with rounding.
904 totalTime = (wlData[2] + 500) / 1000;
905
Amith Yamasani53b707b2009-09-30 11:05:30 -0700906 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -0700907 if (!m.containsKey(name)) {
908 m.put(name, new KernelWakelockStats(count, totalTime,
909 sKernelWakelockUpdateVersion));
910 numUpdatedWlNames++;
911 } else {
912 KernelWakelockStats kwlStats = m.get(name);
913 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
914 kwlStats.mCount += count;
915 kwlStats.mTotalTime += totalTime;
916 } else {
917 kwlStats.mCount = count;
918 kwlStats.mTotalTime = totalTime;
919 kwlStats.mVersion = sKernelWakelockUpdateVersion;
920 numUpdatedWlNames++;
921 }
922 }
Amith Yamasani53b707b2009-09-30 11:05:30 -0700923 }
Evan Millarc64edde2009-04-18 12:26:32 -0700924 startIndex = endIndex;
925 }
926
927 if (m.size() != numUpdatedWlNames) {
928 // Don't report old data.
929 Iterator<KernelWakelockStats> itr = m.values().iterator();
930 while (itr.hasNext()) {
931 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
932 itr.remove();
933 }
934 }
935 }
936 return m;
937 }
938 }
939
940 private class KernelWakelockStats {
941 public int mCount;
942 public long mTotalTime;
943 public int mVersion;
944
945 KernelWakelockStats(int count, long totalTime, int version) {
946 mCount = count;
947 mTotalTime = totalTime;
948 mVersion = version;
949 }
950 }
951
952 /*
953 * Get the KernelWakelockTimer associated with name, and create a new one if one
954 * doesn't already exist.
955 */
956 public SamplingTimer getKernelWakelockTimerLocked(String name) {
957 SamplingTimer kwlt = mKernelWakelockStats.get(name);
958 if (kwlt == null) {
959 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
960 true /* track reported values */);
961 mKernelWakelockStats.put(name, kwlt);
962 }
963 return kwlt;
964 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700965
966 private void doDataPlug(long[] dataTransfer, long currentBytes) {
967 dataTransfer[STATS_LAST] = dataTransfer[STATS_UNPLUGGED];
968 dataTransfer[STATS_UNPLUGGED] = -1;
969 }
970
971 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
972 dataTransfer[STATS_UNPLUGGED] = currentBytes;
973 }
974
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700975 /**
976 * Radio uptime in microseconds when transferring data. This value is very approximate.
977 * @return
978 */
979 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700980 try {
981 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
982 if (!awakeTimeFile.exists()) return 0;
983 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
984 String line = br.readLine();
985 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700986 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700987 } catch (NumberFormatException nfe) {
988 // Nothing
989 } catch (IOException ioe) {
990 // Nothing
991 }
992 return 0;
993 }
994
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700995 /**
996 * @deprecated use getRadioDataUptime
997 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700998 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700999 return getRadioDataUptime() / 1000;
1000 }
1001
1002 /**
1003 * Returns the duration that the cell radio was up for data transfers.
1004 */
1005 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001006 if (mRadioDataStart == -1) {
1007 return mRadioDataUptime;
1008 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001009 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001010 }
1011 }
1012
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001013 private int getCurrentBluetoothPingCount() {
1014 if (mBtHeadset != null) {
1015 return mBtHeadset.getBatteryUsageHint();
1016 }
1017 return -1;
1018 }
1019
1020 public int getBluetoothPingCount() {
1021 if (mBluetoothPingStart == -1) {
1022 return mBluetoothPingCount;
1023 } else if (mBtHeadset != null) {
1024 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1025 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001026 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001027 }
1028
1029 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001030 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1031 mBluetoothPingStart = getCurrentBluetoothPingCount();
1032 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001033 mBtHeadset = headset;
1034 }
1035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036 public void doUnplug(long batteryUptime, long batteryRealtime) {
1037 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1038 Uid u = mUidStats.valueAt(iu);
Ken Shirriff1719a392009-12-07 15:57:35 -08001039 u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid);
1040 u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1042 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1043 }
1044 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1045 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
1046 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001047 // Track total mobile data
Ken Shirriff1719a392009-12-07 15:57:35 -08001048 doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1049 doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1050 doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1051 doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001052 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001053 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001054 mRadioDataUptime = 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001055 // Track bt headset ping count
1056 mBluetoothPingStart = getCurrentBluetoothPingCount();
1057 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 public void doPlug(long batteryUptime, long batteryRealtime) {
1061 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1062 Uid u = mUidStats.valueAt(iu);
1063 if (u.mStartedTcpBytesReceived >= 0) {
1064 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1065 u.mStartedTcpBytesReceived = -1;
1066 }
1067 if (u.mStartedTcpBytesSent >= 0) {
1068 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1069 u.mStartedTcpBytesSent = -1;
1070 }
1071 }
1072 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1073 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
1074 }
Ken Shirriff1719a392009-12-07 15:57:35 -08001075 doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1076 doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1077 doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1078 doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001079 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001080 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001081 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001082
1083 // Track bt headset ping count
1084 mBluetoothPingCount = getBluetoothPingCount();
1085 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001086 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 public void noteStartGps(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001089 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001090 }
1091
1092 public void noteStopGps(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001093 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 public void noteScreenOnLocked() {
1097 if (!mScreenOn) {
1098 mScreenOn = true;
1099 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001100 if (mScreenBrightnessBin >= 0) {
1101 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 }
1104 }
1105
1106 public void noteScreenOffLocked() {
1107 if (mScreenOn) {
1108 mScreenOn = false;
1109 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001110 if (mScreenBrightnessBin >= 0) {
1111 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1112 }
1113 }
1114 }
1115
1116 public void noteScreenBrightnessLocked(int brightness) {
1117 // Bin the brightness.
1118 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1119 if (bin < 0) bin = 0;
1120 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1121 if (mScreenBrightnessBin != bin) {
1122 if (mScreenOn) {
1123 if (mScreenBrightnessBin >= 0) {
1124 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1125 }
1126 mScreenBrightnessTimer[bin].startRunningLocked(this);
1127 }
1128 mScreenBrightnessBin = bin;
1129 }
1130 }
1131
Christopher Tate4cee7252010-03-19 14:50:40 -07001132 public void noteInputEventAtomic() {
1133 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001134 }
1135
1136 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001137 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001138 }
1139
1140 public void notePhoneOnLocked() {
1141 if (!mPhoneOn) {
1142 mPhoneOn = true;
1143 mPhoneOnTimer.startRunningLocked(this);
1144 }
1145 }
1146
1147 public void notePhoneOffLocked() {
1148 if (mPhoneOn) {
1149 mPhoneOn = false;
1150 mPhoneOnTimer.stopRunningLocked(this);
1151 }
1152 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001153
Amith Yamasanif37447b2009-10-08 18:28:01 -07001154 /**
1155 * Telephony stack updates the phone state.
1156 * @param state phone state from ServiceState.getState()
1157 */
1158 public void notePhoneStateLocked(int state) {
1159 int bin = mPhoneSignalStrengthBin;
1160 boolean isAirplaneMode = state == ServiceState.STATE_POWER_OFF;
1161 // Stop all timers
1162 if (isAirplaneMode || state == ServiceState.STATE_OUT_OF_SERVICE) {
1163 for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
1164 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1165 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001166 }
1167 }
1168 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07001169 // Stop Signal Scanning timer, in case we're going into service
1170 while (mPhoneSignalScanningTimer.isRunningLocked()) {
1171 mPhoneSignalScanningTimer.stopRunningLocked(this);
1172 }
1173
1174 // If we're back in service or continuing in service, restart the old timer.
1175 if (state == ServiceState.STATE_IN_SERVICE) {
1176 if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1177 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1178 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1179 }
1180 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
1181 mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1182 if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) {
1183 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this);
1184 }
1185 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
1186 mPhoneSignalScanningTimer.startRunningLocked(this);
1187 }
1188 }
1189 mPhoneServiceState = state;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001190 }
1191
Wink Savillee9b06d72009-05-18 21:47:50 -07001192 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001193 // Bin the strength.
1194 int bin;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001195 if (mPhoneServiceState == ServiceState.STATE_POWER_OFF
1196 || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) {
1197 // Ignore any signal strength changes when radio was turned off or out of service.
1198 return;
1199 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001200 if (!signalStrength.isGsm()) {
1201 int dBm = signalStrength.getCdmaDbm();
Amith Yamasanif37447b2009-10-08 18:28:01 -07001202 if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
1203 else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD;
1204 else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE;
1205 else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR;
1206 else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Wink Savillee9b06d72009-05-18 21:47:50 -07001207 } else {
1208 int asu = signalStrength.getGsmSignalStrength();
1209 if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1210 else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
1211 else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD;
1212 else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE;
1213 else bin = SIGNAL_STRENGTH_POOR;
1214 }
Dianne Hackborn627bba72009-03-24 22:32:56 -07001215 if (mPhoneSignalStrengthBin != bin) {
1216 if (mPhoneSignalStrengthBin >= 0) {
1217 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1218 }
1219 mPhoneSignalStrengthBin = bin;
1220 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1221 }
1222 }
1223
1224 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1225 int bin = DATA_CONNECTION_NONE;
1226 if (hasData) {
1227 switch (dataType) {
1228 case TelephonyManager.NETWORK_TYPE_EDGE:
1229 bin = DATA_CONNECTION_EDGE;
1230 break;
1231 case TelephonyManager.NETWORK_TYPE_GPRS:
1232 bin = DATA_CONNECTION_GPRS;
1233 break;
1234 case TelephonyManager.NETWORK_TYPE_UMTS:
1235 bin = DATA_CONNECTION_UMTS;
1236 break;
1237 default:
1238 bin = DATA_CONNECTION_OTHER;
1239 break;
1240 }
1241 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001242 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001243 if (mPhoneDataConnectionType != bin) {
1244 if (mPhoneDataConnectionType >= 0) {
1245 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
1246 }
1247 mPhoneDataConnectionType = bin;
1248 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
1249 }
1250 }
1251
Dianne Hackborn617f8772009-03-31 15:04:46 -07001252 public void noteWifiOnLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001253 if (!mWifiOn) {
1254 mWifiOn = true;
1255 mWifiOnTimer.startRunningLocked(this);
1256 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001257 if (mWifiOnUid != uid) {
1258 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001259 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001260 }
1261 mWifiOnUid = uid;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001262 getUidStatsLocked(uid).noteWifiTurnedOnLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001263 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001264 }
1265
Dianne Hackborn617f8772009-03-31 15:04:46 -07001266 public void noteWifiOffLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001267 if (mWifiOn) {
1268 mWifiOn = false;
1269 mWifiOnTimer.stopRunningLocked(this);
1270 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001271 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001272 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001273 mWifiOnUid = -1;
1274 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001275 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001276
1277 public void noteAudioOnLocked(int uid) {
1278 if (!mAudioOn) {
1279 mAudioOn = true;
1280 mAudioOnTimer.startRunningLocked(this);
1281 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001282 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001283 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001284
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001285 public void noteAudioOffLocked(int uid) {
1286 if (mAudioOn) {
1287 mAudioOn = false;
1288 mAudioOnTimer.stopRunningLocked(this);
1289 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001290 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001291 }
1292
1293 public void noteVideoOnLocked(int uid) {
1294 if (!mVideoOn) {
1295 mVideoOn = true;
1296 mVideoOnTimer.startRunningLocked(this);
1297 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001298 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001299 }
1300
1301 public void noteVideoOffLocked(int uid) {
1302 if (mVideoOn) {
1303 mVideoOn = false;
1304 mVideoOnTimer.stopRunningLocked(this);
1305 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001306 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001307 }
1308
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001309 public void noteWifiRunningLocked() {
1310 if (!mWifiRunning) {
1311 mWifiRunning = true;
1312 mWifiRunningTimer.startRunningLocked(this);
1313 }
1314 }
1315
1316 public void noteWifiStoppedLocked() {
1317 if (mWifiRunning) {
1318 mWifiRunning = false;
1319 mWifiRunningTimer.stopRunningLocked(this);
1320 }
1321 }
1322
The Android Open Source Project10592532009-03-18 17:39:46 -07001323 public void noteBluetoothOnLocked() {
1324 if (!mBluetoothOn) {
1325 mBluetoothOn = true;
1326 mBluetoothOnTimer.startRunningLocked(this);
1327 }
1328 }
1329
1330 public void noteBluetoothOffLocked() {
1331 if (mBluetoothOn) {
1332 mBluetoothOn = false;
1333 mBluetoothOnTimer.stopRunningLocked(this);
1334 }
1335 }
1336
1337 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001338 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001339 }
1340
1341 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001342 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001343 }
1344
1345 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001346 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001347 }
1348
1349 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001350 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001351 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001352
1353 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001354 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001355 }
1356
1357 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001358 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001359 }
1360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001362 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 }
1364
Dianne Hackborn617f8772009-03-31 15:04:46 -07001365 @Override public long getScreenBrightnessTime(int brightnessBin,
1366 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001367 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07001368 batteryRealtime, which);
1369 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001370
Dianne Hackborn617f8772009-03-31 15:04:46 -07001371 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001372 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001373 }
1374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001376 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001378
Dianne Hackborn627bba72009-03-24 22:32:56 -07001379 @Override public long getPhoneSignalStrengthTime(int strengthBin,
1380 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001381 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001382 batteryRealtime, which);
1383 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07001384
1385 @Override public long getPhoneSignalScanningTime(
1386 long batteryRealtime, int which) {
1387 return mPhoneSignalScanningTimer.getTotalTimeLocked(
1388 batteryRealtime, which);
1389 }
1390
Dianne Hackborn617f8772009-03-31 15:04:46 -07001391 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001392 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001393 }
1394
Dianne Hackborn627bba72009-03-24 22:32:56 -07001395 @Override public long getPhoneDataConnectionTime(int dataType,
1396 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001397 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001398 batteryRealtime, which);
1399 }
1400
Dianne Hackborn617f8772009-03-31 15:04:46 -07001401 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001402 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001403 }
1404
The Android Open Source Project10592532009-03-18 17:39:46 -07001405 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001406 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001407 }
1408
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001409 @Override public long getWifiRunningTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001410 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001411 }
1412
The Android Open Source Project10592532009-03-18 17:39:46 -07001413 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001414 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001415 }
1416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 @Override public boolean getIsOnBattery() {
1418 return mOnBattery;
1419 }
1420
1421 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
1422 return mUidStats;
1423 }
1424
1425 /**
1426 * The statistics associated with a particular uid.
1427 */
1428 public final class Uid extends BatteryStats.Uid {
1429
1430 final int mUid;
1431 long mLoadedTcpBytesReceived;
1432 long mLoadedTcpBytesSent;
1433 long mCurrentTcpBytesReceived;
1434 long mCurrentTcpBytesSent;
1435 long mTcpBytesReceivedAtLastUnplug;
1436 long mTcpBytesSentAtLastUnplug;
1437
1438 // These are not saved/restored when parcelling, since we want
1439 // to return from the parcel with a snapshot of the state.
1440 long mStartedTcpBytesReceived = -1;
1441 long mStartedTcpBytesSent = -1;
1442
Dianne Hackborn617f8772009-03-31 15:04:46 -07001443 boolean mWifiTurnedOn;
Evan Millarc64edde2009-04-18 12:26:32 -07001444 StopwatchTimer mWifiTurnedOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -07001445
The Android Open Source Project10592532009-03-18 17:39:46 -07001446 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001447 StopwatchTimer mFullWifiLockTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -07001448
1449 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001450 StopwatchTimer mScanWifiLockTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001451
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001452 boolean mWifiMulticastEnabled;
1453 StopwatchTimer mWifiMulticastTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001454
1455 boolean mAudioTurnedOn;
1456 StopwatchTimer mAudioTurnedOnTimer;
1457
1458 boolean mVideoTurnedOn;
1459 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001460
Dianne Hackborn617f8772009-03-31 15:04:46 -07001461 Counter[] mUserActivityCounters;
1462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 /**
1464 * The statistics we have collected for this uid's wake locks.
1465 */
1466 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
1467
1468 /**
1469 * The statistics we have collected for this uid's sensor activations.
1470 */
1471 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
1472
1473 /**
1474 * The statistics we have collected for this uid's processes.
1475 */
1476 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
1477
1478 /**
1479 * The statistics we have collected for this uid's processes.
1480 */
1481 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
1482
1483 public Uid(int uid) {
1484 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001485 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables);
1486 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables);
1487 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001488 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1489 null, mUnpluggables);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001490 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables);
1491 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 }
1493
1494 @Override
1495 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
1496 return mWakelockStats;
1497 }
1498
1499 @Override
1500 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
1501 return mSensorStats;
1502 }
1503
1504 @Override
1505 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
1506 return mProcessStats;
1507 }
1508
1509 @Override
1510 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
1511 return mPackageStats;
1512 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001513
1514 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 public int getUid() {
1516 return mUid;
1517 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001518
1519 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 public long getTcpBytesReceived(int which) {
1521 if (which == STATS_LAST) {
1522 return mLoadedTcpBytesReceived;
1523 } else {
1524 long current = computeCurrentTcpBytesReceived();
1525 if (which == STATS_UNPLUGGED) {
1526 current -= mTcpBytesReceivedAtLastUnplug;
1527 } else if (which == STATS_TOTAL) {
1528 current += mLoadedTcpBytesReceived;
1529 }
1530 return current;
1531 }
1532 }
1533
1534 public long computeCurrentTcpBytesReceived() {
1535 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08001536 ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001538
1539 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 public long getTcpBytesSent(int which) {
1541 if (which == STATS_LAST) {
1542 return mLoadedTcpBytesSent;
1543 } else {
1544 long current = computeCurrentTcpBytesSent();
1545 if (which == STATS_UNPLUGGED) {
1546 current -= mTcpBytesSentAtLastUnplug;
1547 } else if (which == STATS_TOTAL) {
1548 current += mLoadedTcpBytesSent;
1549 }
1550 return current;
1551 }
1552 }
1553
The Android Open Source Project10592532009-03-18 17:39:46 -07001554 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07001555 public void noteWifiTurnedOnLocked() {
1556 if (!mWifiTurnedOn) {
1557 mWifiTurnedOn = true;
1558 mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1559 }
1560 }
1561
1562 @Override
1563 public void noteWifiTurnedOffLocked() {
1564 if (mWifiTurnedOn) {
1565 mWifiTurnedOn = false;
1566 mWifiTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1567 }
1568 }
1569
1570 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07001571 public void noteFullWifiLockAcquiredLocked() {
1572 if (!mFullWifiLockOut) {
1573 mFullWifiLockOut = true;
1574 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1575 }
1576 }
1577
1578 @Override
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001579 public void noteVideoTurnedOnLocked() {
1580 if (!mVideoTurnedOn) {
1581 mVideoTurnedOn = true;
1582 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1583 }
1584 }
1585
1586 @Override
1587 public void noteVideoTurnedOffLocked() {
1588 if (mVideoTurnedOn) {
1589 mVideoTurnedOn = false;
1590 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1591 }
1592 }
1593
1594 @Override
1595 public void noteAudioTurnedOnLocked() {
1596 if (!mAudioTurnedOn) {
1597 mAudioTurnedOn = true;
1598 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1599 }
1600 }
1601
1602 @Override
1603 public void noteAudioTurnedOffLocked() {
1604 if (mAudioTurnedOn) {
1605 mAudioTurnedOn = false;
1606 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1607 }
1608 }
1609
1610 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07001611 public void noteFullWifiLockReleasedLocked() {
1612 if (mFullWifiLockOut) {
1613 mFullWifiLockOut = false;
1614 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1615 }
1616 }
1617
1618 @Override
1619 public void noteScanWifiLockAcquiredLocked() {
1620 if (!mScanWifiLockOut) {
1621 mScanWifiLockOut = true;
1622 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1623 }
1624 }
1625
1626 @Override
1627 public void noteScanWifiLockReleasedLocked() {
1628 if (mScanWifiLockOut) {
1629 mScanWifiLockOut = false;
1630 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1631 }
1632 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001633
1634 @Override
1635 public void noteWifiMulticastEnabledLocked() {
1636 if (!mWifiMulticastEnabled) {
1637 mWifiMulticastEnabled = true;
1638 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
1639 }
1640 }
1641
1642 @Override
1643 public void noteWifiMulticastDisabledLocked() {
1644 if (mWifiMulticastEnabled) {
1645 mWifiMulticastEnabled = false;
1646 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
1647 }
1648 }
1649
Dianne Hackborn617f8772009-03-31 15:04:46 -07001650 @Override
1651 public long getWifiTurnedOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001652 return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001653 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001654
1655 @Override
1656 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
1657 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
1658 }
1659
1660 @Override
1661 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
1662 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
1663 }
1664
The Android Open Source Project10592532009-03-18 17:39:46 -07001665 @Override
1666 public long getFullWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001667 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001668 }
1669
1670 @Override
1671 public long getScanWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001672 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001673 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001674
1675 @Override
1676 public long getWifiMulticastTime(long batteryRealtime, int which) {
1677 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
1678 which);
1679 }
1680
Dianne Hackborn617f8772009-03-31 15:04:46 -07001681 @Override
1682 public void noteUserActivityLocked(int type) {
1683 if (mUserActivityCounters == null) {
1684 initUserActivityLocked();
1685 }
1686 if (type < 0) type = 0;
1687 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
Christopher Tate4cee7252010-03-19 14:50:40 -07001688 mUserActivityCounters[type].stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001689 }
1690
1691 @Override
1692 public boolean hasUserActivity() {
1693 return mUserActivityCounters != null;
1694 }
1695
1696 @Override
1697 public int getUserActivityCount(int type, int which) {
1698 if (mUserActivityCounters == null) {
1699 return 0;
1700 }
Evan Millarc64edde2009-04-18 12:26:32 -07001701 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001702 }
1703
1704 void initUserActivityLocked() {
1705 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1706 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1707 mUserActivityCounters[i] = new Counter(mUnpluggables);
1708 }
1709 }
1710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 public long computeCurrentTcpBytesSent() {
1712 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08001713 ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1717 out.writeInt(mWakelockStats.size());
1718 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
1719 out.writeString(wakelockEntry.getKey());
1720 Uid.Wakelock wakelock = wakelockEntry.getValue();
1721 wakelock.writeToParcelLocked(out, batteryRealtime);
1722 }
1723
1724 out.writeInt(mSensorStats.size());
1725 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
1726 out.writeInt(sensorEntry.getKey());
1727 Uid.Sensor sensor = sensorEntry.getValue();
1728 sensor.writeToParcelLocked(out, batteryRealtime);
1729 }
1730
1731 out.writeInt(mProcessStats.size());
1732 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
1733 out.writeString(procEntry.getKey());
1734 Uid.Proc proc = procEntry.getValue();
1735 proc.writeToParcelLocked(out);
1736 }
1737
1738 out.writeInt(mPackageStats.size());
1739 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
1740 out.writeString(pkgEntry.getKey());
1741 Uid.Pkg pkg = pkgEntry.getValue();
1742 pkg.writeToParcelLocked(out);
1743 }
1744
1745 out.writeLong(mLoadedTcpBytesReceived);
1746 out.writeLong(mLoadedTcpBytesSent);
1747 out.writeLong(computeCurrentTcpBytesReceived());
1748 out.writeLong(computeCurrentTcpBytesSent());
1749 out.writeLong(mTcpBytesReceivedAtLastUnplug);
1750 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001751 mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001752 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001753 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
1754 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001755 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001756 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001757 if (mUserActivityCounters == null) {
1758 out.writeInt(0);
1759 } else {
1760 out.writeInt(1);
1761 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1762 mUserActivityCounters[i].writeToParcel(out);
1763 }
1764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001765 }
1766
1767 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1768 int numWakelocks = in.readInt();
1769 mWakelockStats.clear();
1770 for (int j = 0; j < numWakelocks; j++) {
1771 String wakelockName = in.readString();
1772 Uid.Wakelock wakelock = new Wakelock();
1773 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001774 if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) {
1775 // We will just drop some random set of wakelocks if
1776 // the previous run of the system was an older version
1777 // that didn't impose a limit.
1778 mWakelockStats.put(wakelockName, wakelock);
1779 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 }
1781
1782 int numSensors = in.readInt();
1783 mSensorStats.clear();
1784 for (int k = 0; k < numSensors; k++) {
1785 int sensorNumber = in.readInt();
1786 Uid.Sensor sensor = new Sensor(sensorNumber);
1787 sensor.readFromParcelLocked(mUnpluggables, in);
1788 mSensorStats.put(sensorNumber, sensor);
1789 }
1790
1791 int numProcs = in.readInt();
1792 mProcessStats.clear();
1793 for (int k = 0; k < numProcs; k++) {
1794 String processName = in.readString();
1795 Uid.Proc proc = new Proc();
1796 proc.readFromParcelLocked(in);
1797 mProcessStats.put(processName, proc);
1798 }
1799
1800 int numPkgs = in.readInt();
1801 mPackageStats.clear();
1802 for (int l = 0; l < numPkgs; l++) {
1803 String packageName = in.readString();
1804 Uid.Pkg pkg = new Pkg();
1805 pkg.readFromParcelLocked(in);
1806 mPackageStats.put(packageName, pkg);
1807 }
1808
1809 mLoadedTcpBytesReceived = in.readLong();
1810 mLoadedTcpBytesSent = in.readLong();
1811 mCurrentTcpBytesReceived = in.readLong();
1812 mCurrentTcpBytesSent = in.readLong();
1813 mTcpBytesReceivedAtLastUnplug = in.readLong();
1814 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001815 mWifiTurnedOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001816 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001817 mFullWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001818 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables, in);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001819 mAudioTurnedOn = false;
1820 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables, in);
1821 mVideoTurnedOn = false;
1822 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001823 mScanWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001824 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables, in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001825 mWifiMulticastEnabled = false;
1826 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1827 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001828 if (in.readInt() == 0) {
1829 mUserActivityCounters = null;
1830 } else {
1831 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1832 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1833 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
1834 }
1835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001836 }
1837
1838 /**
1839 * The statistics associated with a particular wake lock.
1840 */
1841 public final class Wakelock extends BatteryStats.Uid.Wakelock {
1842 /**
1843 * How long (in ms) this uid has been keeping the device partially awake.
1844 */
Evan Millarc64edde2009-04-18 12:26:32 -07001845 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846
1847 /**
1848 * How long (in ms) this uid has been keeping the device fully awake.
1849 */
Evan Millarc64edde2009-04-18 12:26:32 -07001850 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001851
1852 /**
1853 * How long (in ms) this uid has had a window keeping the device awake.
1854 */
Evan Millarc64edde2009-04-18 12:26:32 -07001855 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856
1857 /**
1858 * Reads a possibly null Timer from a Parcel. The timer is associated with the
1859 * proper timer pool from the given BatteryStatsImpl object.
1860 *
1861 * @param in the Parcel to be read from.
1862 * return a new Timer, or null.
1863 */
Evan Millarc64edde2009-04-18 12:26:32 -07001864 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 ArrayList<Unpluggable> unpluggables, Parcel in) {
1866 if (in.readInt() == 0) {
1867 return null;
1868 }
1869
Evan Millarc64edde2009-04-18 12:26:32 -07001870 return new StopwatchTimer(type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 }
1872
1873 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1874 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
1875 mPartialTimers, unpluggables, in);
1876 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
1877 mFullTimers, unpluggables, in);
1878 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
1879 mWindowTimers, unpluggables, in);
1880 }
1881
1882 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1883 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
1884 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
1885 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
1886 }
1887
1888 @Override
1889 public Timer getWakeTime(int type) {
1890 switch (type) {
1891 case WAKE_TYPE_FULL: return mTimerFull;
1892 case WAKE_TYPE_PARTIAL: return mTimerPartial;
1893 case WAKE_TYPE_WINDOW: return mTimerWindow;
1894 default: throw new IllegalArgumentException("type = " + type);
1895 }
1896 }
1897 }
1898
1899 public final class Sensor extends BatteryStats.Uid.Sensor {
1900 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07001901 StopwatchTimer mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001902
1903 public Sensor(int handle) {
1904 mHandle = handle;
1905 }
1906
Evan Millarc64edde2009-04-18 12:26:32 -07001907 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 Parcel in) {
1909 if (in.readInt() == 0) {
1910 return null;
1911 }
1912
Evan Millarc64edde2009-04-18 12:26:32 -07001913 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001914 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001915 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 mSensorTimers.put(mHandle, pool);
1917 }
Evan Millarc64edde2009-04-18 12:26:32 -07001918 return new StopwatchTimer(0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001919 }
1920
1921 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1922 mTimer = readTimerFromParcel(unpluggables, in);
1923 }
1924
1925 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1926 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
1927 }
1928
1929 @Override
1930 public Timer getSensorTime() {
1931 return mTimer;
1932 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001933
1934 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001935 public int getHandle() {
1936 return mHandle;
1937 }
1938 }
1939
1940 /**
1941 * The statistics associated with a particular process.
1942 */
1943 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
1944 /**
1945 * Total time (in 1/100 sec) spent executing in user code.
1946 */
1947 long mUserTime;
1948
1949 /**
1950 * Total time (in 1/100 sec) spent executing in kernel code.
1951 */
1952 long mSystemTime;
1953
1954 /**
1955 * Number of times the process has been started.
1956 */
1957 int mStarts;
1958
1959 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001960 * Amount of time the process was running in the foreground.
1961 */
1962 long mForegroundTime;
1963
1964 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001965 * The amount of user time loaded from a previous save.
1966 */
1967 long mLoadedUserTime;
1968
1969 /**
1970 * The amount of system time loaded from a previous save.
1971 */
1972 long mLoadedSystemTime;
1973
1974 /**
1975 * The number of times the process has started from a previous save.
1976 */
1977 int mLoadedStarts;
1978
1979 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001980 * The amount of foreground time loaded from a previous save.
1981 */
1982 long mLoadedForegroundTime;
1983
1984 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001985 * The amount of user time loaded from the previous run.
1986 */
1987 long mLastUserTime;
1988
1989 /**
1990 * The amount of system time loaded from the previous run.
1991 */
1992 long mLastSystemTime;
1993
1994 /**
1995 * The number of times the process has started from the previous run.
1996 */
1997 int mLastStarts;
1998
1999 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002000 * The amount of foreground time loaded from the previous run
2001 */
2002 long mLastForegroundTime;
2003
2004 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002005 * The amount of user time when last unplugged.
2006 */
2007 long mUnpluggedUserTime;
2008
2009 /**
2010 * The amount of system time when last unplugged.
2011 */
2012 long mUnpluggedSystemTime;
2013
2014 /**
2015 * The number of times the process has started before unplugged.
2016 */
2017 int mUnpluggedStarts;
2018
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002019 /**
2020 * The amount of foreground time since unplugged.
2021 */
2022 long mUnpluggedForegroundTime;
2023
Amith Yamasanie43530a2009-08-21 13:11:37 -07002024 SamplingCounter[] mSpeedBins;
2025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002026 Proc() {
2027 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002028 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
2029 for (int i = 0; i < mSpeedBins.length; i++) {
2030 mSpeedBins[i] = new SamplingCounter(mUnpluggables);
2031 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002032 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002034 public void unplug(long batteryUptime, long batteryRealtime) {
2035 mUnpluggedUserTime = mUserTime;
2036 mUnpluggedSystemTime = mSystemTime;
2037 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002038 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002039 }
2040
2041 public void plug(long batteryUptime, long batteryRealtime) {
2042 }
2043
2044 void writeToParcelLocked(Parcel out) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002045 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
2046 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
2047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002048 out.writeLong(mUserTime);
2049 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002050 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051 out.writeInt(mStarts);
2052 out.writeLong(mLoadedUserTime);
2053 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002054 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002055 out.writeInt(mLoadedStarts);
2056 out.writeLong(mLastUserTime);
2057 out.writeLong(mLastSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002058 out.writeLong(mLastForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002059 out.writeInt(mLastStarts);
2060 out.writeLong(mUnpluggedUserTime);
2061 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002062 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002063 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002064
2065 out.writeInt(mSpeedBins.length);
2066 for (int i = 0; i < mSpeedBins.length; i++) {
2067 mSpeedBins[i].writeToParcel(out);
2068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002069 }
2070
2071 void readFromParcelLocked(Parcel in) {
2072 mUserTime = in.readLong();
2073 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002074 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002075 mStarts = in.readInt();
2076 mLoadedUserTime = in.readLong();
2077 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002078 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002079 mLoadedStarts = in.readInt();
2080 mLastUserTime = in.readLong();
2081 mLastSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002082 mLastForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083 mLastStarts = in.readInt();
2084 mUnpluggedUserTime = in.readLong();
2085 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002086 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002087 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07002088
2089 int bins = in.readInt();
2090 mSpeedBins = new SamplingCounter[bins];
2091 for (int i = 0; i < bins; i++) {
2092 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
2093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 }
2095
2096 public BatteryStatsImpl getBatteryStats() {
2097 return BatteryStatsImpl.this;
2098 }
2099
2100 public void addCpuTimeLocked(int utime, int stime) {
2101 mUserTime += utime;
2102 mSystemTime += stime;
2103 }
2104
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002105 public void addForegroundTimeLocked(long ttime) {
2106 mForegroundTime += ttime;
2107 }
2108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 public void incStartsLocked() {
2110 mStarts++;
2111 }
2112
2113 @Override
2114 public long getUserTime(int which) {
2115 long val;
2116 if (which == STATS_LAST) {
2117 val = mLastUserTime;
2118 } else {
2119 val = mUserTime;
2120 if (which == STATS_CURRENT) {
2121 val -= mLoadedUserTime;
2122 } else if (which == STATS_UNPLUGGED) {
2123 val -= mUnpluggedUserTime;
2124 }
2125 }
2126 return val;
2127 }
2128
2129 @Override
2130 public long getSystemTime(int which) {
2131 long val;
2132 if (which == STATS_LAST) {
2133 val = mLastSystemTime;
2134 } else {
2135 val = mSystemTime;
2136 if (which == STATS_CURRENT) {
2137 val -= mLoadedSystemTime;
2138 } else if (which == STATS_UNPLUGGED) {
2139 val -= mUnpluggedSystemTime;
2140 }
2141 }
2142 return val;
2143 }
2144
2145 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002146 public long getForegroundTime(int which) {
2147 long val;
2148 if (which == STATS_LAST) {
2149 val = mLastForegroundTime;
2150 } else {
2151 val = mForegroundTime;
2152 if (which == STATS_CURRENT) {
2153 val -= mLoadedForegroundTime;
2154 } else if (which == STATS_UNPLUGGED) {
2155 val -= mUnpluggedForegroundTime;
2156 }
2157 }
2158 return val;
2159 }
2160
2161 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002162 public int getStarts(int which) {
2163 int val;
2164 if (which == STATS_LAST) {
2165 val = mLastStarts;
2166 } else {
2167 val = mStarts;
2168 if (which == STATS_CURRENT) {
2169 val -= mLoadedStarts;
2170 } else if (which == STATS_UNPLUGGED) {
2171 val -= mUnpluggedStarts;
2172 }
2173 }
2174 return val;
2175 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002176
2177 /* Called by ActivityManagerService when CPU times are updated. */
2178 public void addSpeedStepTimes(long[] values) {
2179 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Christopher Tate4cee7252010-03-19 14:50:40 -07002180 mSpeedBins[i].addCountAtomic(values[i]);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002181 }
2182 }
2183
2184 @Override
2185 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
2186 if (speedStep < mSpeedBins.length) {
2187 return mSpeedBins[speedStep].getCountLocked(which);
2188 } else {
2189 return 0;
2190 }
2191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192 }
2193
2194 /**
2195 * The statistics associated with a particular package.
2196 */
2197 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
2198 /**
2199 * Number of times this package has done something that could wake up the
2200 * device from sleep.
2201 */
2202 int mWakeups;
2203
2204 /**
2205 * Number of things that could wake up the device loaded from a
2206 * previous save.
2207 */
2208 int mLoadedWakeups;
2209
2210 /**
2211 * Number of things that could wake up the device as of the
2212 * last run.
2213 */
2214 int mLastWakeups;
2215
2216 /**
2217 * Number of things that could wake up the device as of the
2218 * last run.
2219 */
2220 int mUnpluggedWakeups;
2221
2222 /**
2223 * The statics we have collected for this package's services.
2224 */
2225 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
2226
2227 Pkg() {
2228 mUnpluggables.add(this);
2229 }
2230
2231 public void unplug(long batteryUptime, long batteryRealtime) {
2232 mUnpluggedWakeups = mWakeups;
2233 }
2234
2235 public void plug(long batteryUptime, long batteryRealtime) {
2236 }
2237
2238 void readFromParcelLocked(Parcel in) {
2239 mWakeups = in.readInt();
2240 mLoadedWakeups = in.readInt();
2241 mLastWakeups = in.readInt();
2242 mUnpluggedWakeups = in.readInt();
2243
2244 int numServs = in.readInt();
2245 mServiceStats.clear();
2246 for (int m = 0; m < numServs; m++) {
2247 String serviceName = in.readString();
2248 Uid.Pkg.Serv serv = new Serv();
2249 mServiceStats.put(serviceName, serv);
2250
2251 serv.readFromParcelLocked(in);
2252 }
2253 }
2254
2255 void writeToParcelLocked(Parcel out) {
2256 out.writeInt(mWakeups);
2257 out.writeInt(mLoadedWakeups);
2258 out.writeInt(mLastWakeups);
2259 out.writeInt(mUnpluggedWakeups);
2260
2261 out.writeInt(mServiceStats.size());
2262 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
2263 out.writeString(servEntry.getKey());
2264 Uid.Pkg.Serv serv = servEntry.getValue();
2265
2266 serv.writeToParcelLocked(out);
2267 }
2268 }
2269
2270 @Override
2271 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
2272 return mServiceStats;
2273 }
2274
2275 @Override
2276 public int getWakeups(int which) {
2277 int val;
2278 if (which == STATS_LAST) {
2279 val = mLastWakeups;
2280 } else {
2281 val = mWakeups;
2282 if (which == STATS_CURRENT) {
2283 val -= mLoadedWakeups;
2284 } else if (which == STATS_UNPLUGGED) {
2285 val -= mUnpluggedWakeups;
2286 }
2287 }
2288
2289 return val;
2290 }
2291
2292 /**
2293 * The statistics associated with a particular service.
2294 */
2295 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
2296 /**
2297 * Total time (ms in battery uptime) the service has been left started.
2298 */
2299 long mStartTime;
2300
2301 /**
2302 * If service has been started and not yet stopped, this is
2303 * when it was started.
2304 */
2305 long mRunningSince;
2306
2307 /**
2308 * True if we are currently running.
2309 */
2310 boolean mRunning;
2311
2312 /**
2313 * Total number of times startService() has been called.
2314 */
2315 int mStarts;
2316
2317 /**
2318 * Total time (ms in battery uptime) the service has been left launched.
2319 */
2320 long mLaunchedTime;
2321
2322 /**
2323 * If service has been launched and not yet exited, this is
2324 * when it was launched (ms in battery uptime).
2325 */
2326 long mLaunchedSince;
2327
2328 /**
2329 * True if we are currently launched.
2330 */
2331 boolean mLaunched;
2332
2333 /**
2334 * Total number times the service has been launched.
2335 */
2336 int mLaunches;
2337
2338 /**
2339 * The amount of time spent started loaded from a previous save
2340 * (ms in battery uptime).
2341 */
2342 long mLoadedStartTime;
2343
2344 /**
2345 * The number of starts loaded from a previous save.
2346 */
2347 int mLoadedStarts;
2348
2349 /**
2350 * The number of launches loaded from a previous save.
2351 */
2352 int mLoadedLaunches;
2353
2354 /**
2355 * The amount of time spent started as of the last run (ms
2356 * in battery uptime).
2357 */
2358 long mLastStartTime;
2359
2360 /**
2361 * The number of starts as of the last run.
2362 */
2363 int mLastStarts;
2364
2365 /**
2366 * The number of launches as of the last run.
2367 */
2368 int mLastLaunches;
2369
2370 /**
2371 * The amount of time spent started when last unplugged (ms
2372 * in battery uptime).
2373 */
2374 long mUnpluggedStartTime;
2375
2376 /**
2377 * The number of starts when last unplugged.
2378 */
2379 int mUnpluggedStarts;
2380
2381 /**
2382 * The number of launches when last unplugged.
2383 */
2384 int mUnpluggedLaunches;
2385
2386 Serv() {
2387 mUnpluggables.add(this);
2388 }
2389
2390 public void unplug(long batteryUptime, long batteryRealtime) {
2391 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
2392 mUnpluggedStarts = mStarts;
2393 mUnpluggedLaunches = mLaunches;
2394 }
2395
2396 public void plug(long batteryUptime, long batteryRealtime) {
2397 }
2398
2399 void readFromParcelLocked(Parcel in) {
2400 mStartTime = in.readLong();
2401 mRunningSince = in.readLong();
2402 mRunning = in.readInt() != 0;
2403 mStarts = in.readInt();
2404 mLaunchedTime = in.readLong();
2405 mLaunchedSince = in.readLong();
2406 mLaunched = in.readInt() != 0;
2407 mLaunches = in.readInt();
2408 mLoadedStartTime = in.readLong();
2409 mLoadedStarts = in.readInt();
2410 mLoadedLaunches = in.readInt();
2411 mLastStartTime = in.readLong();
2412 mLastStarts = in.readInt();
2413 mLastLaunches = in.readInt();
2414 mUnpluggedStartTime = in.readLong();
2415 mUnpluggedStarts = in.readInt();
2416 mUnpluggedLaunches = in.readInt();
2417 }
2418
2419 void writeToParcelLocked(Parcel out) {
2420 out.writeLong(mStartTime);
2421 out.writeLong(mRunningSince);
2422 out.writeInt(mRunning ? 1 : 0);
2423 out.writeInt(mStarts);
2424 out.writeLong(mLaunchedTime);
2425 out.writeLong(mLaunchedSince);
2426 out.writeInt(mLaunched ? 1 : 0);
2427 out.writeInt(mLaunches);
2428 out.writeLong(mLoadedStartTime);
2429 out.writeInt(mLoadedStarts);
2430 out.writeInt(mLoadedLaunches);
2431 out.writeLong(mLastStartTime);
2432 out.writeInt(mLastStarts);
2433 out.writeInt(mLastLaunches);
2434 out.writeLong(mUnpluggedStartTime);
2435 out.writeInt(mUnpluggedStarts);
2436 out.writeInt(mUnpluggedLaunches);
2437 }
2438
2439 long getLaunchTimeToNowLocked(long batteryUptime) {
2440 if (!mLaunched) return mLaunchedTime;
2441 return mLaunchedTime + batteryUptime - mLaunchedSince;
2442 }
2443
2444 long getStartTimeToNowLocked(long batteryUptime) {
2445 if (!mRunning) return mStartTime;
2446 return mStartTime + batteryUptime - mRunningSince;
2447 }
2448
2449 public void startLaunchedLocked() {
2450 if (!mLaunched) {
2451 mLaunches++;
2452 mLaunchedSince = getBatteryUptimeLocked();
2453 mLaunched = true;
2454 }
2455 }
2456
2457 public void stopLaunchedLocked() {
2458 if (mLaunched) {
2459 long time = getBatteryUptimeLocked() - mLaunchedSince;
2460 if (time > 0) {
2461 mLaunchedTime += time;
2462 } else {
2463 mLaunches--;
2464 }
2465 mLaunched = false;
2466 }
2467 }
2468
2469 public void startRunningLocked() {
2470 if (!mRunning) {
2471 mStarts++;
2472 mRunningSince = getBatteryUptimeLocked();
2473 mRunning = true;
2474 }
2475 }
2476
2477 public void stopRunningLocked() {
2478 if (mRunning) {
2479 long time = getBatteryUptimeLocked() - mRunningSince;
2480 if (time > 0) {
2481 mStartTime += time;
2482 } else {
2483 mStarts--;
2484 }
2485 mRunning = false;
2486 }
2487 }
2488
2489 public BatteryStatsImpl getBatteryStats() {
2490 return BatteryStatsImpl.this;
2491 }
2492
2493 @Override
2494 public int getLaunches(int which) {
2495 int val;
2496
2497 if (which == STATS_LAST) {
2498 val = mLastLaunches;
2499 } else {
2500 val = mLaunches;
2501 if (which == STATS_CURRENT) {
2502 val -= mLoadedLaunches;
2503 } else if (which == STATS_UNPLUGGED) {
2504 val -= mUnpluggedLaunches;
2505 }
2506 }
2507
2508 return val;
2509 }
2510
2511 @Override
2512 public long getStartTime(long now, int which) {
2513 long val;
2514 if (which == STATS_LAST) {
2515 val = mLastStartTime;
2516 } else {
2517 val = getStartTimeToNowLocked(now);
2518 if (which == STATS_CURRENT) {
2519 val -= mLoadedStartTime;
2520 } else if (which == STATS_UNPLUGGED) {
2521 val -= mUnpluggedStartTime;
2522 }
2523 }
2524
2525 return val;
2526 }
2527
2528 @Override
2529 public int getStarts(int which) {
2530 int val;
2531 if (which == STATS_LAST) {
2532 val = mLastStarts;
2533 } else {
2534 val = mStarts;
2535 if (which == STATS_CURRENT) {
2536 val -= mLoadedStarts;
2537 } else if (which == STATS_UNPLUGGED) {
2538 val -= mUnpluggedStarts;
2539 }
2540 }
2541
2542 return val;
2543 }
2544 }
2545
2546 public BatteryStatsImpl getBatteryStats() {
2547 return BatteryStatsImpl.this;
2548 }
2549
2550 public void incWakeupsLocked() {
2551 mWakeups++;
2552 }
2553
2554 final Serv newServiceStatsLocked() {
2555 return new Serv();
2556 }
2557 }
2558
2559 /**
2560 * Retrieve the statistics object for a particular process, creating
2561 * if needed.
2562 */
2563 public Proc getProcessStatsLocked(String name) {
2564 Proc ps = mProcessStats.get(name);
2565 if (ps == null) {
2566 ps = new Proc();
2567 mProcessStats.put(name, ps);
2568 }
2569
2570 return ps;
2571 }
2572
2573 /**
2574 * Retrieve the statistics object for a particular service, creating
2575 * if needed.
2576 */
2577 public Pkg getPackageStatsLocked(String name) {
2578 Pkg ps = mPackageStats.get(name);
2579 if (ps == null) {
2580 ps = new Pkg();
2581 mPackageStats.put(name, ps);
2582 }
2583
2584 return ps;
2585 }
2586
2587 /**
2588 * Retrieve the statistics object for a particular service, creating
2589 * if needed.
2590 */
2591 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
2592 Pkg ps = getPackageStatsLocked(pkg);
2593 Pkg.Serv ss = ps.mServiceStats.get(serv);
2594 if (ss == null) {
2595 ss = ps.newServiceStatsLocked();
2596 ps.mServiceStats.put(serv, ss);
2597 }
2598
2599 return ss;
2600 }
2601
Evan Millarc64edde2009-04-18 12:26:32 -07002602 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002603 Wakelock wl = mWakelockStats.get(name);
2604 if (wl == null) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002605 if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) {
2606 name = BATCHED_WAKELOCK_NAME;
2607 wl = mWakelockStats.get(name);
2608 }
2609 if (wl == null) {
2610 wl = new Wakelock();
2611 mWakelockStats.put(name, wl);
2612 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 }
Evan Millarc64edde2009-04-18 12:26:32 -07002614 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615 switch (type) {
2616 case WAKE_TYPE_PARTIAL:
2617 t = wl.mTimerPartial;
2618 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002619 t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620 wl.mTimerPartial = t;
2621 }
2622 return t;
2623 case WAKE_TYPE_FULL:
2624 t = wl.mTimerFull;
2625 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002626 t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 wl.mTimerFull = t;
2628 }
2629 return t;
2630 case WAKE_TYPE_WINDOW:
2631 t = wl.mTimerWindow;
2632 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002633 t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002634 wl.mTimerWindow = t;
2635 }
2636 return t;
2637 default:
2638 throw new IllegalArgumentException("type=" + type);
2639 }
2640 }
2641
Evan Millarc64edde2009-04-18 12:26:32 -07002642 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002643 Sensor se = mSensorStats.get(sensor);
2644 if (se == null) {
2645 if (!create) {
2646 return null;
2647 }
2648 se = new Sensor(sensor);
2649 mSensorStats.put(sensor, se);
2650 }
Evan Millarc64edde2009-04-18 12:26:32 -07002651 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 if (t != null) {
2653 return t;
2654 }
Evan Millarc64edde2009-04-18 12:26:32 -07002655 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002657 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658 mSensorTimers.put(sensor, timers);
2659 }
Evan Millarc64edde2009-04-18 12:26:32 -07002660 t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 se.mTimer = t;
2662 return t;
2663 }
2664
2665 public void noteStartWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002666 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 if (t != null) {
2668 t.startRunningLocked(BatteryStatsImpl.this);
2669 }
2670 }
2671
2672 public void noteStopWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002673 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674 if (t != null) {
2675 t.stopRunningLocked(BatteryStatsImpl.this);
2676 }
2677 }
2678
2679 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07002680 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002681 if (t != null) {
2682 t.startRunningLocked(BatteryStatsImpl.this);
2683 }
2684 }
2685
2686 public void noteStopSensor(int sensor) {
2687 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07002688 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002689 if (t != null) {
2690 t.stopRunningLocked(BatteryStatsImpl.this);
2691 }
2692 }
2693
2694 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002695 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 if (t != null) {
2697 t.startRunningLocked(BatteryStatsImpl.this);
2698 }
2699 }
2700
2701 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002702 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002703 if (t != null) {
2704 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002705 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002706 }
2707
2708 public BatteryStatsImpl getBatteryStats() {
2709 return BatteryStatsImpl.this;
2710 }
2711 }
2712
2713 public BatteryStatsImpl(String filename) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07002714 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002715 mStartCount++;
Evan Millarc64edde2009-04-18 12:26:32 -07002716 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002717 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002718 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002719 }
2720 mInputEventCounter = new Counter(mUnpluggables);
Evan Millarc64edde2009-04-18 12:26:32 -07002721 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002722 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002723 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002724 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002725 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002726 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002727 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002728 }
Evan Millarc64edde2009-04-18 12:26:32 -07002729 mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables);
2730 mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables);
2731 mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables);
Mike Chan18d200f2010-02-02 10:33:45 -08002732 mAudioOnTimer = new StopwatchTimer(-6, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 mOnBattery = mOnBatteryInternal = false;
2734 mTrackBatteryPastUptime = 0;
2735 mTrackBatteryPastRealtime = 0;
2736 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
2737 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
2738 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
2739 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07002740 mDischargeStartLevel = 0;
2741 mDischargeCurrentLevel = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002742 }
2743
2744 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07002745 mFile = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 readFromParcel(p);
2747 }
2748
Amith Yamasanie43530a2009-08-21 13:11:37 -07002749 public void setNumSpeedSteps(int steps) {
2750 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
2751 }
2752
Amith Yamasanif37447b2009-10-08 18:28:01 -07002753 public void setRadioScanningTimeout(long timeout) {
2754 if (mPhoneSignalScanningTimer != null) {
2755 mPhoneSignalScanningTimer.setTimeout(timeout);
2756 }
2757 }
2758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759 @Override
2760 public int getStartCount() {
2761 return mStartCount;
2762 }
2763
2764 public boolean isOnBattery() {
2765 return mOnBattery;
2766 }
2767
The Android Open Source Project10592532009-03-18 17:39:46 -07002768 public void setOnBattery(boolean onBattery, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002769 synchronized(this) {
Evan Millarc64edde2009-04-18 12:26:32 -07002770 updateKernelWakelocksLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002771 if (mOnBattery != onBattery) {
2772 mOnBattery = mOnBatteryInternal = onBattery;
2773
2774 long uptime = SystemClock.uptimeMillis() * 1000;
2775 long mSecRealtime = SystemClock.elapsedRealtime();
2776 long realtime = mSecRealtime * 1000;
2777 if (onBattery) {
2778 mTrackBatteryUptimeStart = uptime;
2779 mTrackBatteryRealtimeStart = realtime;
2780 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
2781 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
Evan Millar633a1742009-04-02 16:36:33 -07002782 mDischargeCurrentLevel = mDischargeStartLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002783 doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
2784 } else {
2785 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
2786 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
Evan Millar633a1742009-04-02 16:36:33 -07002787 mDischargeCurrentLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002788 doPlug(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
2789 }
2790 if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) {
2791 if (mFile != null) {
2792 writeLocked();
2793 }
2794 }
2795 }
2796 }
2797 }
Evan Millar633a1742009-04-02 16:36:33 -07002798
2799 public void recordCurrentLevel(int level) {
2800 mDischargeCurrentLevel = level;
2801 }
Evan Millarc64edde2009-04-18 12:26:32 -07002802
2803 public void updateKernelWakelocksLocked() {
2804 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
2805
Marco Nelissend8593312009-04-30 14:45:06 -07002806 if (m == null) {
2807 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07002808 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07002809 return;
2810 }
2811
Evan Millarc64edde2009-04-18 12:26:32 -07002812 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
2813 String name = ent.getKey();
2814 KernelWakelockStats kws = ent.getValue();
2815
2816 SamplingTimer kwlt = mKernelWakelockStats.get(name);
2817 if (kwlt == null) {
2818 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
2819 true /* track reported values */);
2820 mKernelWakelockStats.put(name, kwlt);
2821 }
2822 kwlt.updateCurrentReportedCount(kws.mCount);
2823 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
2824 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
2825 }
2826
2827 if (m.size() != mKernelWakelockStats.size()) {
2828 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
2829 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
2830 SamplingTimer st = ent.getValue();
2831 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
2832 st.setStale();
2833 }
2834 }
2835 }
2836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002837
2838 public long getAwakeTimeBattery() {
2839 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
2840 }
2841
2842 public long getAwakeTimePlugged() {
2843 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
2844 }
2845
2846 @Override
2847 public long computeUptime(long curTime, int which) {
2848 switch (which) {
2849 case STATS_TOTAL: return mUptime + (curTime-mUptimeStart);
2850 case STATS_LAST: return mLastUptime;
2851 case STATS_CURRENT: return (curTime-mUptimeStart);
2852 case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
2853 }
2854 return 0;
2855 }
2856
2857 @Override
2858 public long computeRealtime(long curTime, int which) {
2859 switch (which) {
2860 case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart);
2861 case STATS_LAST: return mLastRealtime;
2862 case STATS_CURRENT: return (curTime-mRealtimeStart);
2863 case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
2864 }
2865 return 0;
2866 }
2867
2868 @Override
2869 public long computeBatteryUptime(long curTime, int which) {
2870 switch (which) {
2871 case STATS_TOTAL:
2872 return mBatteryUptime + getBatteryUptime(curTime);
2873 case STATS_LAST:
2874 return mBatteryLastUptime;
2875 case STATS_CURRENT:
2876 return getBatteryUptime(curTime);
2877 case STATS_UNPLUGGED:
2878 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
2879 }
2880 return 0;
2881 }
2882
2883 @Override
2884 public long computeBatteryRealtime(long curTime, int which) {
2885 switch (which) {
2886 case STATS_TOTAL:
2887 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
2888 case STATS_LAST:
2889 return mBatteryLastRealtime;
2890 case STATS_CURRENT:
2891 return getBatteryRealtimeLocked(curTime);
2892 case STATS_UNPLUGGED:
2893 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
2894 }
2895 return 0;
2896 }
2897
2898 long getBatteryUptimeLocked(long curTime) {
2899 long time = mTrackBatteryPastUptime;
2900 if (mOnBatteryInternal) {
2901 time += curTime - mTrackBatteryUptimeStart;
2902 }
2903 return time;
2904 }
2905
2906 long getBatteryUptimeLocked() {
2907 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
2908 }
2909
2910 @Override
2911 public long getBatteryUptime(long curTime) {
2912 return getBatteryUptimeLocked(curTime);
2913 }
2914
2915 long getBatteryRealtimeLocked(long curTime) {
2916 long time = mTrackBatteryPastRealtime;
2917 if (mOnBatteryInternal) {
2918 time += curTime - mTrackBatteryRealtimeStart;
2919 }
2920 return time;
2921 }
2922
2923 @Override
2924 public long getBatteryRealtime(long curTime) {
2925 return getBatteryRealtimeLocked(curTime);
2926 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002927
2928 private long getTcpBytes(long current, long[] dataBytes, int which) {
2929 if (which == STATS_LAST) {
2930 return dataBytes[STATS_LAST];
2931 } else {
2932 if (which == STATS_UNPLUGGED) {
2933 if (dataBytes[STATS_UNPLUGGED] < 0) {
2934 return dataBytes[STATS_LAST];
2935 } else {
2936 return current - dataBytes[STATS_UNPLUGGED];
2937 }
2938 } else if (which == STATS_TOTAL) {
2939 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_TOTAL];
2940 }
2941 return current - dataBytes[STATS_CURRENT];
2942 }
2943 }
2944
2945 /** Only STATS_UNPLUGGED works properly */
2946 public long getMobileTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08002947 return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002948 }
2949
2950 /** Only STATS_UNPLUGGED works properly */
2951 public long getMobileTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08002952 return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002953 }
2954
2955 /** Only STATS_UNPLUGGED works properly */
2956 public long getTotalTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08002957 return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002958 }
2959
2960 /** Only STATS_UNPLUGGED works properly */
2961 public long getTotalTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08002962 return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002963 }
2964
The Android Open Source Project10592532009-03-18 17:39:46 -07002965 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002966 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002967 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002968 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002969 }
2970 }
2971
Evan Millar633a1742009-04-02 16:36:33 -07002972 public int getDischargeStartLevelLocked() {
2973 return mDischargeStartLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002974 }
2975
2976 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002977 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002978 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002979 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002980 }
2981 }
2982
Evan Millar633a1742009-04-02 16:36:33 -07002983 public int getDischargeCurrentLevelLocked() {
2984 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986
Amith Yamasanie43530a2009-08-21 13:11:37 -07002987 @Override
2988 public int getCpuSpeedSteps() {
2989 return sNumSpeedSteps;
2990 }
2991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 /**
2993 * Retrieve the statistics object for a particular uid, creating if needed.
2994 */
2995 public Uid getUidStatsLocked(int uid) {
2996 Uid u = mUidStats.get(uid);
2997 if (u == null) {
2998 u = new Uid(uid);
2999 mUidStats.put(uid, u);
3000 }
3001 return u;
3002 }
3003
3004 /**
3005 * Remove the statistics object for a particular uid.
3006 */
3007 public void removeUidStatsLocked(int uid) {
3008 mUidStats.remove(uid);
3009 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003011 /**
3012 * Retrieve the statistics object for a particular process, creating
3013 * if needed.
3014 */
3015 public Uid.Proc getProcessStatsLocked(int uid, String name) {
3016 Uid u = getUidStatsLocked(uid);
3017 return u.getProcessStatsLocked(name);
3018 }
3019
3020 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003021 * Retrieve the statistics object for a particular process, given
3022 * the name of the process.
3023 * @param name process name
3024 * @return the statistics object for the process
3025 */
Amith Yamasani819f9282009-06-24 23:18:15 -07003026 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003027 int uid;
3028 if (mUidCache.containsKey(name)) {
3029 uid = mUidCache.get(name);
3030 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07003031 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003032 mUidCache.put(name, uid);
3033 }
3034 Uid u = getUidStatsLocked(uid);
3035 return u.getProcessStatsLocked(name);
3036 }
3037
3038 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003039 * Retrieve the statistics object for a particular process, creating
3040 * if needed.
3041 */
3042 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
3043 Uid u = getUidStatsLocked(uid);
3044 return u.getPackageStatsLocked(pkg);
3045 }
3046
3047 /**
3048 * Retrieve the statistics object for a particular service, creating
3049 * if needed.
3050 */
3051 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
3052 Uid u = getUidStatsLocked(uid);
3053 return u.getServiceStatsLocked(pkg, name);
3054 }
3055
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003056 private static JournaledFile makeJournaledFile() {
3057 final String base = "/data/system/device_policies.xml";
3058 return new JournaledFile(new File(base), new File(base + ".tmp"));
3059 }
3060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 public void writeLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003062 if (mFile == null) {
3063 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003064 return;
3065 }
3066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003067 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003068 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 Parcel out = Parcel.obtain();
3070 writeSummaryToParcel(out);
3071 stream.write(out.marshall());
3072 out.recycle();
3073
3074 stream.flush();
3075 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003076 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003077
3078 mLastWriteTime = SystemClock.elapsedRealtime();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07003079 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003080 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003081 Slog.w("BatteryStats", "Error writing battery statistics", e);
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07003082 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003083 mFile.rollback();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 }
3085
3086 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
3087 int pos = 0;
3088 int avail = stream.available();
3089 byte[] data = new byte[avail];
3090 while (true) {
3091 int amt = stream.read(data, pos, data.length-pos);
3092 //Log.i("foo", "Read " + amt + " bytes at " + pos
3093 // + " of avail " + data.length);
3094 if (amt <= 0) {
3095 //Log.i("foo", "**** FINISHED READING: pos=" + pos
3096 // + " len=" + data.length);
3097 return data;
3098 }
3099 pos += amt;
3100 avail = stream.available();
3101 if (avail > data.length-pos) {
3102 byte[] newData = new byte[pos+avail];
3103 System.arraycopy(data, 0, newData, 0, pos);
3104 data = newData;
3105 }
3106 }
3107 }
3108
3109 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003110 if (mFile == null) {
3111 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003112 return;
3113 }
3114
3115 mUidStats.clear();
3116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003117 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003118 File file = mFile.chooseForRead();
3119 if (!file.exists()) {
3120 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003121 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003122 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003123
3124 byte[] raw = readFully(stream);
3125 Parcel in = Parcel.obtain();
3126 in.unmarshall(raw, 0, raw.length);
3127 in.setDataPosition(0);
3128 stream.close();
3129
3130 readSummaryFromParcel(in);
3131 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003132 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003133 }
3134 }
3135
3136 public int describeContents() {
3137 return 0;
3138 }
3139
3140 private void readSummaryFromParcel(Parcel in) {
3141 final int version = in.readInt();
3142 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003143 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003144 + ", expected " + VERSION + "; erasing old stats");
3145 return;
3146 }
3147
3148 mStartCount = in.readInt();
3149 mBatteryUptime = in.readLong();
3150 mBatteryLastUptime = in.readLong();
3151 mBatteryRealtime = in.readLong();
3152 mBatteryLastRealtime = in.readLong();
3153 mUptime = in.readLong();
3154 mLastUptime = in.readLong();
3155 mRealtime = in.readLong();
3156 mLastRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07003157 mDischargeStartLevel = in.readInt();
3158 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project10592532009-03-18 17:39:46 -07003159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003160 mStartCount++;
3161
3162 mScreenOn = false;
3163 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003164 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3165 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
3166 }
3167 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003168 mPhoneOn = false;
3169 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003170 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3171 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
3172 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003173 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003174 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3175 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
3176 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003177 mWifiOn = false;
3178 mWifiOnTimer.readSummaryFromParcelLocked(in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003179 mWifiRunning = false;
3180 mWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003181 mBluetoothOn = false;
3182 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003183
Evan Millarc64edde2009-04-18 12:26:32 -07003184 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003185 if (NKW > 10000) {
3186 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
3187 return;
3188 }
Evan Millarc64edde2009-04-18 12:26:32 -07003189 for (int ikw = 0; ikw < NKW; ikw++) {
3190 if (in.readInt() != 0) {
3191 String kwltName = in.readString();
3192 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
3193 }
3194 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003195
3196 sNumSpeedSteps = in.readInt();
3197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003198 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003199 if (NU > 10000) {
3200 Slog.w(TAG, "File corrupt: too many uids " + NU);
3201 return;
3202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003203 for (int iu = 0; iu < NU; iu++) {
3204 int uid = in.readInt();
3205 Uid u = new Uid(uid);
3206 mUidStats.put(uid, u);
3207
Dianne Hackborn617f8772009-03-31 15:04:46 -07003208 u.mWifiTurnedOn = false;
3209 u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003210 u.mFullWifiLockOut = false;
3211 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003212 u.mAudioTurnedOn = false;
3213 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
3214 u.mVideoTurnedOn = false;
3215 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003216 u.mScanWifiLockOut = false;
3217 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003218 u.mWifiMulticastEnabled = false;
3219 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
3220
Dianne Hackborn617f8772009-03-31 15:04:46 -07003221 if (in.readInt() != 0) {
3222 if (u.mUserActivityCounters == null) {
3223 u.initUserActivityLocked();
3224 }
3225 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3226 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
3227 }
3228 }
3229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003230 int NW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003231 if (NW > 10000) {
3232 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
3233 return;
3234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003235 for (int iw = 0; iw < NW; iw++) {
3236 String wlName = in.readString();
3237 if (in.readInt() != 0) {
3238 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
3239 }
3240 if (in.readInt() != 0) {
3241 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
3242 }
3243 if (in.readInt() != 0) {
3244 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
3245 }
3246 }
3247
3248 int NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003249 if (NP > 10000) {
3250 Slog.w(TAG, "File corrupt: too many sensors " + NP);
3251 return;
3252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003253 for (int is = 0; is < NP; is++) {
3254 int seNumber = in.readInt();
3255 if (in.readInt() != 0) {
3256 u.getSensorTimerLocked(seNumber, true)
3257 .readSummaryFromParcelLocked(in);
3258 }
3259 }
3260
3261 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003262 if (NP > 10000) {
3263 Slog.w(TAG, "File corrupt: too many processes " + NP);
3264 return;
3265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003266 for (int ip = 0; ip < NP; ip++) {
3267 String procName = in.readString();
3268 Uid.Proc p = u.getProcessStatsLocked(procName);
3269 p.mUserTime = p.mLoadedUserTime = in.readLong();
3270 p.mLastUserTime = in.readLong();
3271 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
3272 p.mLastSystemTime = in.readLong();
3273 p.mStarts = p.mLoadedStarts = in.readInt();
3274 p.mLastStarts = in.readInt();
3275 }
3276
3277 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003278 if (NP > 10000) {
3279 Slog.w(TAG, "File corrupt: too many packages " + NP);
3280 return;
3281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003282 for (int ip = 0; ip < NP; ip++) {
3283 String pkgName = in.readString();
3284 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
3285 p.mWakeups = p.mLoadedWakeups = in.readInt();
3286 p.mLastWakeups = in.readInt();
3287 final int NS = in.readInt();
3288 for (int is = 0; is < NS; is++) {
3289 String servName = in.readString();
3290 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
3291 s.mStartTime = s.mLoadedStartTime = in.readLong();
3292 s.mLastStartTime = in.readLong();
3293 s.mStarts = s.mLoadedStarts = in.readInt();
3294 s.mLastStarts = in.readInt();
3295 s.mLaunches = s.mLoadedLaunches = in.readInt();
3296 s.mLastLaunches = in.readInt();
3297 }
3298 }
3299
3300 u.mLoadedTcpBytesReceived = in.readLong();
3301 u.mLoadedTcpBytesSent = in.readLong();
3302 }
3303 }
3304
3305 /**
3306 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
3307 * disk. This format does not allow a lossless round-trip.
3308 *
3309 * @param out the Parcel to be written to.
3310 */
3311 public void writeSummaryToParcel(Parcel out) {
3312 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
3313 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
3314 final long NOW = getBatteryUptimeLocked(NOW_SYS);
3315 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
3316
3317 out.writeInt(VERSION);
3318
3319 out.writeInt(mStartCount);
3320 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_TOTAL));
3321 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_CURRENT));
3322 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_TOTAL));
3323 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_CURRENT));
3324 out.writeLong(computeUptime(NOW_SYS, STATS_TOTAL));
3325 out.writeLong(computeUptime(NOW_SYS, STATS_CURRENT));
3326 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_TOTAL));
3327 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_CURRENT));
Evan Millar633a1742009-04-02 16:36:33 -07003328 out.writeInt(mDischargeStartLevel);
3329 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project10592532009-03-18 17:39:46 -07003330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003331
3332 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003333 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3334 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3335 }
3336 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003337 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003338 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3339 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3340 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003341 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003342 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3343 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3344 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003345 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003346 mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003347 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348
Evan Millarc64edde2009-04-18 12:26:32 -07003349 out.writeInt(mKernelWakelockStats.size());
3350 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3351 Timer kwlt = ent.getValue();
3352 if (kwlt != null) {
3353 out.writeInt(1);
3354 out.writeString(ent.getKey());
3355 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
3356 } else {
3357 out.writeInt(0);
3358 }
3359 }
3360
Amith Yamasanie43530a2009-08-21 13:11:37 -07003361 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 final int NU = mUidStats.size();
3363 out.writeInt(NU);
3364 for (int iu = 0; iu < NU; iu++) {
3365 out.writeInt(mUidStats.keyAt(iu));
3366 Uid u = mUidStats.valueAt(iu);
The Android Open Source Project10592532009-03-18 17:39:46 -07003367
Dianne Hackborn617f8772009-03-31 15:04:46 -07003368 u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003369 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Amith Yamasanic33fe6c2009-05-27 15:29:04 -07003370 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
3371 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003372 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003373 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003374
Dianne Hackborn617f8772009-03-31 15:04:46 -07003375 if (u.mUserActivityCounters == null) {
3376 out.writeInt(0);
3377 } else {
3378 out.writeInt(1);
3379 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3380 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
3381 }
3382 }
3383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384 int NW = u.mWakelockStats.size();
3385 out.writeInt(NW);
3386 if (NW > 0) {
3387 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
3388 : u.mWakelockStats.entrySet()) {
3389 out.writeString(ent.getKey());
3390 Uid.Wakelock wl = ent.getValue();
3391 if (wl.mTimerFull != null) {
3392 out.writeInt(1);
3393 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
3394 } else {
3395 out.writeInt(0);
3396 }
3397 if (wl.mTimerPartial != null) {
3398 out.writeInt(1);
3399 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
3400 } else {
3401 out.writeInt(0);
3402 }
3403 if (wl.mTimerWindow != null) {
3404 out.writeInt(1);
3405 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
3406 } else {
3407 out.writeInt(0);
3408 }
3409 }
3410 }
3411
3412 int NSE = u.mSensorStats.size();
3413 out.writeInt(NSE);
3414 if (NSE > 0) {
3415 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
3416 : u.mSensorStats.entrySet()) {
3417 out.writeInt(ent.getKey());
3418 Uid.Sensor se = ent.getValue();
3419 if (se.mTimer != null) {
3420 out.writeInt(1);
3421 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
3422 } else {
3423 out.writeInt(0);
3424 }
3425 }
3426 }
3427
3428 int NP = u.mProcessStats.size();
3429 out.writeInt(NP);
3430 if (NP > 0) {
3431 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
3432 : u.mProcessStats.entrySet()) {
3433 out.writeString(ent.getKey());
3434 Uid.Proc ps = ent.getValue();
3435 out.writeLong(ps.mUserTime);
3436 out.writeLong(ps.mUserTime - ps.mLoadedUserTime);
3437 out.writeLong(ps.mSystemTime);
3438 out.writeLong(ps.mSystemTime - ps.mLoadedSystemTime);
3439 out.writeInt(ps.mStarts);
3440 out.writeInt(ps.mStarts - ps.mLoadedStarts);
3441 }
3442 }
3443
3444 NP = u.mPackageStats.size();
3445 out.writeInt(NP);
3446 if (NP > 0) {
3447 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
3448 : u.mPackageStats.entrySet()) {
3449 out.writeString(ent.getKey());
3450 Uid.Pkg ps = ent.getValue();
3451 out.writeInt(ps.mWakeups);
3452 out.writeInt(ps.mWakeups - ps.mLoadedWakeups);
3453 final int NS = ps.mServiceStats.size();
3454 out.writeInt(NS);
3455 if (NS > 0) {
3456 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
3457 : ps.mServiceStats.entrySet()) {
3458 out.writeString(sent.getKey());
3459 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
3460 long time = ss.getStartTimeToNowLocked(NOW);
3461 out.writeLong(time);
3462 out.writeLong(time - ss.mLoadedStartTime);
3463 out.writeInt(ss.mStarts);
3464 out.writeInt(ss.mStarts - ss.mLoadedStarts);
3465 out.writeInt(ss.mLaunches);
3466 out.writeInt(ss.mLaunches - ss.mLoadedLaunches);
3467 }
3468 }
3469 }
3470 }
3471
3472 out.writeLong(u.getTcpBytesReceived(STATS_TOTAL));
3473 out.writeLong(u.getTcpBytesSent(STATS_TOTAL));
3474 }
3475 }
3476
3477 public void readFromParcel(Parcel in) {
3478 readFromParcelLocked(in);
3479 }
3480
3481 void readFromParcelLocked(Parcel in) {
3482 int magic = in.readInt();
3483 if (magic != MAGIC) {
3484 throw new ParcelFormatException("Bad magic number");
3485 }
3486
3487 mStartCount = in.readInt();
3488 mBatteryUptime = in.readLong();
3489 mBatteryLastUptime = in.readLong();
3490 mBatteryRealtime = in.readLong();
3491 mBatteryLastRealtime = in.readLong();
3492 mScreenOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003493 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003494 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003495 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003496 }
3497 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 mPhoneOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003499 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003500 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003501 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003502 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003503 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003504 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003505 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003506 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003507 mWifiOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003508 mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003509 mWifiRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003510 mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003511 mBluetoothOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003512 mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 mUptime = in.readLong();
3514 mUptimeStart = in.readLong();
3515 mLastUptime = in.readLong();
3516 mRealtime = in.readLong();
3517 mRealtimeStart = in.readLong();
3518 mLastRealtime = in.readLong();
3519 mOnBattery = in.readInt() != 0;
3520 mOnBatteryInternal = false; // we are no longer really running.
3521 mTrackBatteryPastUptime = in.readLong();
3522 mTrackBatteryUptimeStart = in.readLong();
3523 mTrackBatteryPastRealtime = in.readLong();
3524 mTrackBatteryRealtimeStart = in.readLong();
3525 mUnpluggedBatteryUptime = in.readLong();
3526 mUnpluggedBatteryRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07003527 mDischargeStartLevel = in.readInt();
3528 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003529 mLastWriteTime = in.readLong();
3530
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003531 mMobileDataRx[STATS_LAST] = in.readLong();
3532 mMobileDataRx[STATS_UNPLUGGED] = -1;
3533 mMobileDataTx[STATS_LAST] = in.readLong();
3534 mMobileDataTx[STATS_UNPLUGGED] = -1;
3535 mTotalDataRx[STATS_LAST] = in.readLong();
3536 mTotalDataRx[STATS_UNPLUGGED] = -1;
3537 mTotalDataTx[STATS_LAST] = in.readLong();
3538 mTotalDataTx[STATS_UNPLUGGED] = -1;
3539
3540 mRadioDataUptime = in.readLong();
3541 mRadioDataStart = -1;
3542
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07003543 mBluetoothPingCount = in.readInt();
3544 mBluetoothPingStart = -1;
3545
Evan Millarc64edde2009-04-18 12:26:32 -07003546 mKernelWakelockStats.clear();
3547 int NKW = in.readInt();
3548 for (int ikw = 0; ikw < NKW; ikw++) {
3549 if (in.readInt() != 0) {
3550 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003551 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07003552 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
3553 mKernelWakelockStats.put(wakelockName, kwlt);
3554 }
3555 }
3556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 mPartialTimers.clear();
3558 mFullTimers.clear();
3559 mWindowTimers.clear();
3560
Amith Yamasanie43530a2009-08-21 13:11:37 -07003561 sNumSpeedSteps = in.readInt();
3562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003563 int numUids = in.readInt();
3564 mUidStats.clear();
3565 for (int i = 0; i < numUids; i++) {
3566 int uid = in.readInt();
3567 Uid u = new Uid(uid);
3568 u.readFromParcelLocked(mUnpluggables, in);
3569 mUidStats.append(uid, u);
3570 }
3571 }
3572
3573 public void writeToParcel(Parcel out, int flags) {
3574 writeToParcelLocked(out, flags);
3575 }
3576
3577 @SuppressWarnings("unused")
3578 void writeToParcelLocked(Parcel out, int flags) {
3579 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
3580 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
3581 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
3582 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
3583
3584 out.writeInt(MAGIC);
3585 out.writeInt(mStartCount);
3586 out.writeLong(mBatteryUptime);
3587 out.writeLong(mBatteryLastUptime);
3588 out.writeLong(mBatteryRealtime);
3589 out.writeLong(mBatteryLastRealtime);
3590 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003591 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3592 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
3593 }
3594 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003596 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3597 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
3598 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003599 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003600 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3601 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
3602 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003603 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003604 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003605 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003606 out.writeLong(mUptime);
3607 out.writeLong(mUptimeStart);
3608 out.writeLong(mLastUptime);
3609 out.writeLong(mRealtime);
3610 out.writeLong(mRealtimeStart);
3611 out.writeLong(mLastRealtime);
3612 out.writeInt(mOnBattery ? 1 : 0);
3613 out.writeLong(batteryUptime);
3614 out.writeLong(mTrackBatteryUptimeStart);
3615 out.writeLong(batteryRealtime);
3616 out.writeLong(mTrackBatteryRealtimeStart);
3617 out.writeLong(mUnpluggedBatteryUptime);
3618 out.writeLong(mUnpluggedBatteryRealtime);
Evan Millar633a1742009-04-02 16:36:33 -07003619 out.writeInt(mDischargeStartLevel);
3620 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003621 out.writeLong(mLastWriteTime);
3622
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003623 out.writeLong(getMobileTcpBytesReceived(STATS_UNPLUGGED));
3624 out.writeLong(getMobileTcpBytesSent(STATS_UNPLUGGED));
3625 out.writeLong(getTotalTcpBytesReceived(STATS_UNPLUGGED));
3626 out.writeLong(getTotalTcpBytesSent(STATS_UNPLUGGED));
3627
3628 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07003629 out.writeLong(getRadioDataUptime());
3630
3631 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003632
Evan Millarc64edde2009-04-18 12:26:32 -07003633 out.writeInt(mKernelWakelockStats.size());
3634 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3635 SamplingTimer kwlt = ent.getValue();
3636 if (kwlt != null) {
3637 out.writeInt(1);
3638 out.writeString(ent.getKey());
3639 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
3640 } else {
3641 out.writeInt(0);
3642 }
3643 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003644
3645 out.writeInt(sNumSpeedSteps);
3646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003647 int size = mUidStats.size();
3648 out.writeInt(size);
3649 for (int i = 0; i < size; i++) {
3650 out.writeInt(mUidStats.keyAt(i));
3651 Uid uid = mUidStats.valueAt(i);
3652
3653 uid.writeToParcelLocked(out, batteryRealtime);
3654 }
3655 }
3656
3657 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
3658 new Parcelable.Creator<BatteryStatsImpl>() {
3659 public BatteryStatsImpl createFromParcel(Parcel in) {
3660 return new BatteryStatsImpl(in);
3661 }
3662
3663 public BatteryStatsImpl[] newArray(int size) {
3664 return new BatteryStatsImpl[size];
3665 }
3666 };
3667
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003668 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003670 Printer pr = new PrintWriterPrinter(pw);
3671 pr.println("*** Screen timer:");
3672 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003673 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003674 pr.println("*** Screen brightness #" + i + ":");
3675 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003676 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003677 pr.println("*** Input event counter:");
3678 mInputEventCounter.logState(pr, " ");
3679 pr.println("*** Phone timer:");
3680 mPhoneOnTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003681 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003682 pr.println("*** Signal strength #" + i + ":");
3683 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003684 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003685 pr.println("*** Signal scanning :");
3686 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003687 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003688 pr.println("*** Data connection type #" + i + ":");
3689 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003690 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003691 pr.println("*** Wifi timer:");
3692 mWifiOnTimer.logState(pr, " ");
3693 pr.println("*** WifiRunning timer:");
3694 mWifiRunningTimer.logState(pr, " ");
3695 pr.println("*** Bluetooth timer:");
3696 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 }
3698 super.dumpLocked(pw);
3699 }
3700}