blob: 2847cf3409a534f281e6dc00c917a9bf16f0ad76 [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
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070021import android.bluetooth.BluetoothDevice;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070022import android.bluetooth.BluetoothHeadset;
Ken Shirriff1719a392009-12-07 15:57:35 -080023import android.net.TrafficStats;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070024import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.os.BatteryStats;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070026import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070027import android.os.Handler;
28import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.os.Parcel;
30import android.os.ParcelFormatException;
31import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070032import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.os.SystemClock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070034import android.os.WorkSource;
Amith Yamasanif37447b2009-10-08 18:28:01 -070035import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070036import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070037import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.util.Log;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070039import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070041import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.util.SparseArray;
43
Amith Yamasani3718aaa2009-06-09 06:32:35 -070044import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import java.io.File;
46import java.io.FileInputStream;
47import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070048import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070050import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import java.util.ArrayList;
52import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070053import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070054import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070056import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070057import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
59/**
60 * All information we are collecting about things that can happen that impact
61 * battery life. All times are represented in microseconds except where indicated
62 * otherwise.
63 */
64public final class BatteryStatsImpl extends BatteryStats {
65 private static final String TAG = "BatteryStatsImpl";
66 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070067 private static final boolean DEBUG_HISTORY = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070070 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071
72 // Current on-disk Parcel version
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080073 private static final int VERSION = 54;
Amith Yamasanie43530a2009-08-21 13:11:37 -070074
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070075 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070076 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070077
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070078 // No, really, THIS is the maximum number of items we will record in the history.
79 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
80
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080081 // The maximum number of names wakelocks we will keep track of
82 // per uid; once the limit is reached, we batch the remaining wakelocks
83 // in to one common name.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070084 private static final int MAX_WAKELOCKS_PER_UID = 30;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070085
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080086 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070087
Amith Yamasanie43530a2009-08-21 13:11:37 -070088 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070090 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091
Dianne Hackborn0d903a82010-09-07 23:51:03 -070092 static final int MSG_UPDATE_WAKELOCKS = 1;
93 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -070094 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070095
96 public interface BatteryCallback {
97 public void batteryNeedsCpuUpdate();
98 public void batteryPowerChanged(boolean onBattery);
99 }
100
101 final class MyHandler extends Handler {
102 @Override
103 public void handleMessage(Message msg) {
104 BatteryCallback cb = mCallback;
105 switch (msg.what) {
106 case MSG_UPDATE_WAKELOCKS:
107 if (cb != null) {
108 cb.batteryNeedsCpuUpdate();
109 }
110 break;
111 case MSG_REPORT_POWER_CHANGE:
112 if (cb != null) {
113 cb.batteryPowerChanged(msg.arg1 != 0);
114 }
115 break;
116 }
117 }
118 }
119
120 private final MyHandler mHandler;
121
122 private BatteryCallback mCallback;
123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 /**
125 * The statistics we have collected organized by uids.
126 */
127 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
128 new SparseArray<BatteryStatsImpl.Uid>();
129
130 // A set of pools of currently active timers. When a timer is queried, we will divide the
131 // elapsed time by the number of active timers to arrive at that timer's share of the time.
132 // In order to do this, we must refresh each timer whenever the number of active timers
133 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700134 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
135 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
136 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
137 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
138 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700139 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
140 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
141 final ArrayList<StopwatchTimer> mScanWifiLockTimers = new ArrayList<StopwatchTimer>();
142 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700144 // Last partial timers we use for distributing CPU usage.
145 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 // These are the objects that will want to do something when the device
148 // is unplugged from power.
149 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700150
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700151 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700152
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700153 long mHistoryBaseTime;
154 boolean mHaveBatteryLevel = false;
155 boolean mRecordingHistory = true;
156 int mNumHistoryItems;
157 HistoryItem mHistory;
158 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700159 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700160 HistoryItem mHistoryCache;
161 final HistoryItem mHistoryCur = new HistoryItem();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 int mStartCount;
164
165 long mBatteryUptime;
166 long mBatteryLastUptime;
167 long mBatteryRealtime;
168 long mBatteryLastRealtime;
169
170 long mUptime;
171 long mUptimeStart;
172 long mLastUptime;
173 long mRealtime;
174 long mRealtimeStart;
175 long mLastRealtime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700178 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700179
Dianne Hackborn617f8772009-03-31 15:04:46 -0700180 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700181 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700182
Dianne Hackborn617f8772009-03-31 15:04:46 -0700183 Counter mInputEventCounter;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700186 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700187
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700188 boolean mAudioOn;
189 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700190
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700191 boolean mVideoOn;
192 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700193
Dianne Hackborn627bba72009-03-24 22:32:56 -0700194 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800195 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700196 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800197 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700198
199 StopwatchTimer mPhoneSignalScanningTimer;
200
Dianne Hackborn627bba72009-03-24 22:32:56 -0700201 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700202 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700203 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700204
The Android Open Source Project10592532009-03-18 17:39:46 -0700205 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700206 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700207 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700208
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700209 boolean mGlobalWifiRunning;
210 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700211
The Android Open Source Project10592532009-03-18 17:39:46 -0700212 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700213 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700214
215 /** Bluetooth headset object */
216 BluetoothHeadset mBtHeadset;
217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 /**
219 * These provide time bases that discount the time the device is plugged
220 * in to power.
221 */
222 boolean mOnBattery;
223 boolean mOnBatteryInternal;
224 long mTrackBatteryPastUptime;
225 long mTrackBatteryUptimeStart;
226 long mTrackBatteryPastRealtime;
227 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 long mUnpluggedBatteryUptime;
230 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700231
The Android Open Source Project10592532009-03-18 17:39:46 -0700232 /*
233 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
234 */
Evan Millar633a1742009-04-02 16:36:33 -0700235 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700236 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700237 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700238 int mLowDischargeAmountSinceCharge;
239 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800240 int mDischargeScreenOnUnplugLevel;
241 int mDischargeScreenOffUnplugLevel;
242 int mDischargeAmountScreenOn;
243 int mDischargeAmountScreenOnSinceCharge;
244 int mDischargeAmountScreenOff;
245 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700248
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700249 // Mobile data transferred while on battery
250 private long[] mMobileDataTx = new long[4];
251 private long[] mMobileDataRx = new long[4];
252 private long[] mTotalDataTx = new long[4];
253 private long[] mTotalDataRx = new long[4];
254
255 private long mRadioDataUptime;
256 private long mRadioDataStart;
257
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700258 private int mBluetoothPingCount;
259 private int mBluetoothPingStart = -1;
260
Amith Yamasanif37447b2009-10-08 18:28:01 -0700261 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800262 private int mPhoneServiceStateRaw = -1;
263 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700264
Evan Millarc64edde2009-04-18 12:26:32 -0700265 /*
266 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
267 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700268 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700269 new HashMap<String, SamplingTimer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700270
Evan Millarc64edde2009-04-18 12:26:32 -0700271 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
272 return mKernelWakelockStats;
273 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700274
Evan Millarc64edde2009-04-18 12:26:32 -0700275 private static int sKernelWakelockUpdateVersion = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700276
Evan Millarc64edde2009-04-18 12:26:32 -0700277 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
278 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
279 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
280 Process.PROC_TAB_TERM,
281 Process.PROC_TAB_TERM,
282 Process.PROC_TAB_TERM,
283 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
284 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700285
Evan Millarc64edde2009-04-18 12:26:32 -0700286 private final String[] mProcWakelocksName = new String[3];
287 private final long[] mProcWakelocksData = new long[3];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700288
Evan Millarc64edde2009-04-18 12:26:32 -0700289 /*
290 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
291 * to mKernelWakelockStats.
292 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700293 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700294 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700296 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 // For debugging
299 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700300 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700301 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 }
303
304 public static interface Unpluggable {
305 void unplug(long batteryUptime, long batteryRealtime);
306 void plug(long batteryUptime, long batteryRealtime);
307 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700310 * State for keeping track of counting information.
311 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700312 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700313 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700314 final ArrayList<Unpluggable> mUnpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700315 int mLoadedCount;
316 int mLastCount;
317 int mUnpluggedCount;
318 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700319
Dianne Hackborn617f8772009-03-31 15:04:46 -0700320 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700321 mUnpluggables = unpluggables;
Christopher Tate4cee7252010-03-19 14:50:40 -0700322 mPluggedCount = in.readInt();
323 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700324 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700325 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700326 mUnpluggedCount = in.readInt();
327 unpluggables.add(this);
328 }
329
330 Counter(ArrayList<Unpluggable> unpluggables) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700331 mUnpluggables = unpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700332 unpluggables.add(this);
333 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700334
Dianne Hackborn617f8772009-03-31 15:04:46 -0700335 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700336 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700337 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700338 out.writeInt(mUnpluggedCount);
339 }
340
341 public void unplug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700342 mUnpluggedCount = mPluggedCount;
343 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700344 }
345
346 public void plug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700347 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700348 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700349
Dianne Hackborn617f8772009-03-31 15:04:46 -0700350 /**
351 * Writes a possibly null Counter to a Parcel.
352 *
353 * @param out the Parcel to be written to.
354 * @param counter a Counter, or null.
355 */
356 public static void writeCounterToParcel(Parcel out, Counter counter) {
357 if (counter == null) {
358 out.writeInt(0); // indicates null
359 return;
360 }
361 out.writeInt(1); // indicates non-null
362
363 counter.writeToParcel(out);
364 }
365
366 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700367 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700368 int val;
369 if (which == STATS_LAST) {
370 val = mLastCount;
371 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700372 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700373 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700374 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700375 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700376 val -= mLoadedCount;
377 }
378 }
379
380 return val;
381 }
382
383 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700384 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700385 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
386 + " mUnpluggedCount=" + mUnpluggedCount
387 + " mPluggedCount=" + mPluggedCount);
388 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700389
Christopher Tate4cee7252010-03-19 14:50:40 -0700390 void stepAtomic() {
391 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700392 }
393
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700394 /**
395 * Clear state of this counter.
396 */
397 void reset(boolean detachIfReset) {
398 mCount.set(0);
399 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
400 if (detachIfReset) {
401 detach();
402 }
403 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700404
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700405 void detach() {
406 mUnpluggables.remove(this);
407 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700408
Dianne Hackborn617f8772009-03-31 15:04:46 -0700409 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700410 int count = mCount.get();
411 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700412 }
413
414 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700415 mLoadedCount = in.readInt();
416 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700417 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700418 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700419 }
420 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700421
422 public static class SamplingCounter extends Counter {
423
424 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
425 super(unpluggables, in);
426 }
427
428 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
429 super(unpluggables);
430 }
431
Christopher Tate4cee7252010-03-19 14:50:40 -0700432 public void addCountAtomic(long count) {
433 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700434 }
435 }
436
Dianne Hackborn617f8772009-03-31 15:04:46 -0700437 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 * State for keeping track of timing information.
439 */
Evan Millarc64edde2009-04-18 12:26:32 -0700440 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 final int mType;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700442 final ArrayList<Unpluggable> mUnpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 int mCount;
445 int mLoadedCount;
446 int mLastCount;
447 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 // Times are in microseconds for better accuracy when dividing by the
450 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 /**
453 * The total time we have accumulated since the start of the original
454 * boot, to the last time something interesting happened in the
455 * current run.
456 */
457 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 /**
460 * The total time we loaded for the previous runs. Subtract this from
461 * mTotalTime to find the time for the current run of the system.
462 */
463 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 /**
466 * The run time of the last run of the system, as loaded from the
467 * saved data.
468 */
469 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 /**
472 * The value of mTotalTime when unplug() was last called. Subtract
473 * this from mTotalTime to find the time since the last unplug from
474 * power.
475 */
476 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700477
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700478 /**
479 * Constructs from a parcel.
480 * @param type
481 * @param unpluggables
482 * @param powerType
483 * @param in
484 */
Evan Millarc64edde2009-04-18 12:26:32 -0700485 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700487 mUnpluggables = unpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 mCount = in.readInt();
490 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700491 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 mUnpluggedCount = in.readInt();
493 mTotalTime = in.readLong();
494 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700495 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 mUnpluggedTime = in.readLong();
497 unpluggables.add(this);
498 }
499
Evan Millarc64edde2009-04-18 12:26:32 -0700500 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700502 mUnpluggables = unpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 unpluggables.add(this);
504 }
Evan Millarc64edde2009-04-18 12:26:32 -0700505
506 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700507
Evan Millarc64edde2009-04-18 12:26:32 -0700508 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700509
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700510 /**
511 * Clear state of this timer. Returns true if the timer is inactive
512 * so can be completely dropped.
513 */
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700514 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700515 mTotalTime = mLoadedTime = mLastTime = 0;
516 mCount = mLoadedCount = mLastCount = 0;
517 if (detachIfReset) {
518 detach();
519 }
520 return true;
521 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700522
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700523 void detach() {
524 mUnpluggables.remove(this);
525 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 public void writeToParcel(Parcel out, long batteryRealtime) {
528 out.writeInt(mCount);
529 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 out.writeInt(mUnpluggedCount);
531 out.writeLong(computeRunTimeLocked(batteryRealtime));
532 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 out.writeLong(mUnpluggedTime);
534 }
535
536 public void unplug(long batteryUptime, long batteryRealtime) {
537 if (DEBUG && mType < 0) {
538 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
539 + " old mUnpluggedTime=" + mUnpluggedTime
540 + " old mUnpluggedCount=" + mUnpluggedCount);
541 }
542 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
543 mUnpluggedCount = mCount;
544 if (DEBUG && mType < 0) {
545 Log.v(TAG, "unplug #" + mType
546 + ": new mUnpluggedTime=" + mUnpluggedTime
547 + " new mUnpluggedCount=" + mUnpluggedCount);
548 }
549 }
550
551 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700552 if (DEBUG && mType < 0) {
553 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
554 + " old mTotalTime=" + mTotalTime);
555 }
556 mTotalTime = computeRunTimeLocked(batteryRealtime);
557 mCount = computeCurrentCountLocked();
558 if (DEBUG && mType < 0) {
559 Log.v(TAG, "plug #" + mType
560 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 }
562 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 /**
565 * Writes a possibly null Timer to a Parcel.
566 *
567 * @param out the Parcel to be written to.
568 * @param timer a Timer, or null.
569 */
570 public static void writeTimerToParcel(Parcel out, Timer timer,
571 long batteryRealtime) {
572 if (timer == null) {
573 out.writeInt(0); // indicates null
574 return;
575 }
576 out.writeInt(1); // indicates non-null
577
578 timer.writeToParcel(out, batteryRealtime);
579 }
580
581 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700582 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 long val;
584 if (which == STATS_LAST) {
585 val = mLastTime;
586 } else {
587 val = computeRunTimeLocked(batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700588 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 val -= mUnpluggedTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700590 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 val -= mLoadedTime;
592 }
593 }
594
595 return val;
596 }
597
598 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700599 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 int val;
601 if (which == STATS_LAST) {
602 val = mLastCount;
603 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700604 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700605 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700607 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 val -= mLoadedCount;
609 }
610 }
611
612 return val;
613 }
614
Dianne Hackborn627bba72009-03-24 22:32:56 -0700615 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700616 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
618 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700619 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800620 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700621 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700623 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700624
625
Evan Millarc64edde2009-04-18 12:26:32 -0700626 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
627 long runTime = computeRunTimeLocked(batteryRealtime);
628 // Divide by 1000 for backwards compatibility
629 out.writeLong((runTime + 500) / 1000);
Evan Millarc64edde2009-04-18 12:26:32 -0700630 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -0700631 }
632
633 void readSummaryFromParcelLocked(Parcel in) {
634 // Multiply by 1000 for backwards compatibility
635 mTotalTime = mLoadedTime = in.readLong() * 1000;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700636 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700637 mUnpluggedTime = mTotalTime;
638 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700639 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700640 mUnpluggedCount = mCount;
641 }
642 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700643
Evan Millarc64edde2009-04-18 12:26:32 -0700644 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700645
Evan Millarc64edde2009-04-18 12:26:32 -0700646 /**
647 * The most recent reported count from /proc/wakelocks.
648 */
649 int mCurrentReportedCount;
650
651 /**
652 * The reported count from /proc/wakelocks when unplug() was last
653 * called.
654 */
655 int mUnpluggedReportedCount;
656
657 /**
658 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700659 */
Evan Millarc64edde2009-04-18 12:26:32 -0700660 long mCurrentReportedTotalTime;
661
662
663 /**
664 * The reported total_time from /proc/wakelocks when unplug() was last
665 * called.
666 */
667 long mUnpluggedReportedTotalTime;
668
669 /**
670 * Whether we are currently in a discharge cycle.
671 */
672 boolean mInDischarge;
673
674 /**
675 * Whether we are currently recording reported values.
676 */
677 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700678
Evan Millarc64edde2009-04-18 12:26:32 -0700679 /*
680 * A sequnce counter, incremented once for each update of the stats.
681 */
682 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700683
Evan Millarc64edde2009-04-18 12:26:32 -0700684 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
685 super(0, unpluggables, in);
686 mCurrentReportedCount = in.readInt();
687 mUnpluggedReportedCount = in.readInt();
688 mCurrentReportedTotalTime = in.readLong();
689 mUnpluggedReportedTotalTime = in.readLong();
690 mTrackingReportedValues = in.readInt() == 1;
691 mInDischarge = inDischarge;
692 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700693
694 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
Evan Millarc64edde2009-04-18 12:26:32 -0700695 boolean trackReportedValues) {
696 super(0, unpluggables);
697 mTrackingReportedValues = trackReportedValues;
698 mInDischarge = inDischarge;
699 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700700
Evan Millarc64edde2009-04-18 12:26:32 -0700701 public void setStale() {
702 mTrackingReportedValues = false;
703 mUnpluggedReportedTotalTime = 0;
704 mUnpluggedReportedCount = 0;
705 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700706
Evan Millarc64edde2009-04-18 12:26:32 -0700707 public void setUpdateVersion(int version) {
708 mUpdateVersion = version;
709 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700710
Evan Millarc64edde2009-04-18 12:26:32 -0700711 public int getUpdateVersion() {
712 return mUpdateVersion;
713 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700714
Evan Millarc64edde2009-04-18 12:26:32 -0700715 public void updateCurrentReportedCount(int count) {
716 if (mInDischarge && mUnpluggedReportedCount == 0) {
717 // Updating the reported value for the first time.
718 mUnpluggedReportedCount = count;
719 // If we are receiving an update update mTrackingReportedValues;
720 mTrackingReportedValues = true;
721 }
722 mCurrentReportedCount = count;
723 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700724
Evan Millarc64edde2009-04-18 12:26:32 -0700725 public void updateCurrentReportedTotalTime(long totalTime) {
726 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
727 // Updating the reported value for the first time.
728 mUnpluggedReportedTotalTime = totalTime;
729 // If we are receiving an update update mTrackingReportedValues;
730 mTrackingReportedValues = true;
731 }
732 mCurrentReportedTotalTime = totalTime;
733 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700734
Evan Millarc64edde2009-04-18 12:26:32 -0700735 public void unplug(long batteryUptime, long batteryRealtime) {
736 super.unplug(batteryUptime, batteryRealtime);
737 if (mTrackingReportedValues) {
738 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
739 mUnpluggedReportedCount = mCurrentReportedCount;
740 }
741 mInDischarge = true;
742 }
743
744 public void plug(long batteryUptime, long batteryRealtime) {
745 super.plug(batteryUptime, batteryRealtime);
746 mInDischarge = false;
747 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700748
Evan Millarc64edde2009-04-18 12:26:32 -0700749 public void logState(Printer pw, String prefix) {
750 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700751 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -0700752 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
753 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
754 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
755 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700756
Evan Millarc64edde2009-04-18 12:26:32 -0700757 protected long computeRunTimeLocked(long curBatteryRealtime) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700758 return mTotalTime + (mInDischarge && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -0700759 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
760 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700761
Evan Millarc64edde2009-04-18 12:26:32 -0700762 protected int computeCurrentCountLocked() {
763 return mCount + (mInDischarge && mTrackingReportedValues
764 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
765 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700766
Evan Millarc64edde2009-04-18 12:26:32 -0700767 public void writeToParcel(Parcel out, long batteryRealtime) {
768 super.writeToParcel(out, batteryRealtime);
769 out.writeInt(mCurrentReportedCount);
770 out.writeInt(mUnpluggedReportedCount);
771 out.writeLong(mCurrentReportedTotalTime);
772 out.writeLong(mUnpluggedReportedTotalTime);
773 out.writeInt(mTrackingReportedValues ? 1 : 0);
774 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700775
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700776 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
777 super.reset(stats, detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700778 setStale();
779 return true;
780 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700781
Evan Millarc64edde2009-04-18 12:26:32 -0700782 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
783 super.writeSummaryFromParcelLocked(out, batteryRealtime);
784 out.writeLong(mCurrentReportedTotalTime);
785 out.writeInt(mCurrentReportedCount);
786 out.writeInt(mTrackingReportedValues ? 1 : 0);
787 }
788
789 void readSummaryFromParcelLocked(Parcel in) {
790 super.readSummaryFromParcelLocked(in);
791 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
792 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
793 mTrackingReportedValues = in.readInt() == 1;
794 }
795 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700796
Evan Millarc64edde2009-04-18 12:26:32 -0700797 /**
798 * State for keeping track of timing information.
799 */
800 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700801 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -0700802 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700803
Evan Millarc64edde2009-04-18 12:26:32 -0700804 int mNesting;
805
Evan Millarc64edde2009-04-18 12:26:32 -0700806 /**
807 * The last time at which we updated the timer. If mNesting is > 0,
808 * subtract this from the current battery time to find the amount of
809 * time we have been running since we last computed an update.
810 */
811 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700812
Evan Millarc64edde2009-04-18 12:26:32 -0700813 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700814 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -0700815 * was actually held for an interesting duration.
816 */
817 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700818
Amith Yamasanif37447b2009-10-08 18:28:01 -0700819 long mTimeout;
820
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700821 /**
822 * For partial wake locks, keep track of whether we are in the list
823 * to consume CPU cycles.
824 */
825 boolean mInList;
826
827 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700828 ArrayList<Unpluggable> unpluggables, Parcel in) {
829 super(type, unpluggables, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700830 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700831 mTimerPool = timerPool;
832 mUpdateTime = in.readLong();
833 }
834
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700835 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700836 ArrayList<Unpluggable> unpluggables) {
837 super(type, unpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700838 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700839 mTimerPool = timerPool;
840 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700841
Amith Yamasanif37447b2009-10-08 18:28:01 -0700842 void setTimeout(long timeout) {
843 mTimeout = timeout;
844 }
845
Evan Millarc64edde2009-04-18 12:26:32 -0700846 public void writeToParcel(Parcel out, long batteryRealtime) {
847 super.writeToParcel(out, batteryRealtime);
848 out.writeLong(mUpdateTime);
849 }
850
851 public void plug(long batteryUptime, long batteryRealtime) {
852 if (mNesting > 0) {
853 if (DEBUG && mType < 0) {
854 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
855 }
856 super.plug(batteryUptime, batteryRealtime);
857 mUpdateTime = batteryRealtime;
858 if (DEBUG && mType < 0) {
859 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
860 }
861 }
862 }
863
864 public void logState(Printer pw, String prefix) {
865 super.logState(pw, prefix);
866 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 + " mAcquireTime=" + mAcquireTime);
868 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 void startRunningLocked(BatteryStatsImpl stats) {
871 if (mNesting++ == 0) {
872 mUpdateTime = stats.getBatteryRealtimeLocked(
873 SystemClock.elapsedRealtime() * 1000);
874 if (mTimerPool != null) {
875 // Accumulate time to all currently active timers before adding
876 // this new one to the pool.
877 refreshTimersLocked(stats, mTimerPool);
878 // Add this timer to the active pool
879 mTimerPool.add(this);
880 }
881 // Increment the count
882 mCount++;
883 mAcquireTime = mTotalTime;
884 if (DEBUG && mType < 0) {
885 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
886 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
887 + " mAcquireTime=" + mAcquireTime);
888 }
889 }
890 }
891
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700892 boolean isRunningLocked() {
893 return mNesting > 0;
894 }
895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 void stopRunningLocked(BatteryStatsImpl stats) {
897 // Ignore attempt to stop a timer that isn't running
898 if (mNesting == 0) {
899 return;
900 }
901 if (--mNesting == 0) {
902 if (mTimerPool != null) {
903 // Accumulate time to all active counters, scaled by the total
904 // active in the pool, before taking this one out of the pool.
905 refreshTimersLocked(stats, mTimerPool);
906 // Remove this timer from the active pool
907 mTimerPool.remove(this);
908 } else {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700909 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
911 mNesting = 1;
912 mTotalTime = computeRunTimeLocked(batteryRealtime);
913 mNesting = 0;
914 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 if (DEBUG && mType < 0) {
917 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
918 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
919 + " mAcquireTime=" + mAcquireTime);
920 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 if (mTotalTime == mAcquireTime) {
923 // If there was no change in the time, then discard this
924 // count. A somewhat cheezy strategy, but hey.
925 mCount--;
926 }
927 }
928 }
929
930 // Update the total time for all other running Timers with the same type as this Timer
931 // due to a change in timer count
932 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700933 final ArrayList<StopwatchTimer> pool) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700934 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
936 final int N = pool.size();
937 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700938 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 long heldTime = batteryRealtime - t.mUpdateTime;
940 if (heldTime > 0) {
941 t.mTotalTime += heldTime / N;
942 }
943 t.mUpdateTime = batteryRealtime;
944 }
945 }
946
Evan Millarc64edde2009-04-18 12:26:32 -0700947 @Override
948 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700949 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
950 curBatteryRealtime = mUpdateTime + mTimeout;
951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 return mTotalTime + (mNesting > 0
953 ? (curBatteryRealtime - mUpdateTime)
954 / (mTimerPool != null ? mTimerPool.size() : 1)
955 : 0);
956 }
957
Evan Millarc64edde2009-04-18 12:26:32 -0700958 @Override
959 protected int computeCurrentCountLocked() {
960 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 }
962
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700963 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700964 boolean canDetach = mNesting <= 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700965 super.reset(stats, canDetach && detachIfReset);
966 if (mNesting > 0) {
967 mUpdateTime = stats.getBatteryRealtimeLocked(
968 SystemClock.elapsedRealtime() * 1000);
969 }
970 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700971 return canDetach;
972 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700973
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700974 void detach() {
975 super.detach();
976 if (mTimerPool != null) {
977 mTimerPool.remove(this);
978 }
979 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -0700982 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 mNesting = 0;
984 }
985 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700986
Evan Millarc64edde2009-04-18 12:26:32 -0700987 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700988
Johannes Carlsson3372f2e2010-06-30 08:45:55 +0200989 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -0700990 int len;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700991
Evan Millarc64edde2009-04-18 12:26:32 -0700992 try {
993 FileInputStream is = new FileInputStream("/proc/wakelocks");
994 len = is.read(buffer);
995 is.close();
996
997 if (len > 0) {
998 int i;
999 for (i=0; i<len; i++) {
1000 if (buffer[i] == '\0') {
1001 len = i;
1002 break;
1003 }
1004 }
1005 }
1006 } catch (java.io.FileNotFoundException e) {
1007 return null;
1008 } catch (java.io.IOException e) {
1009 return null;
1010 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001011
Evan Millarc64edde2009-04-18 12:26:32 -07001012 return parseProcWakelocks(buffer, len);
1013 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001014
Evan Millarc64edde2009-04-18 12:26:32 -07001015 private final Map<String, KernelWakelockStats> parseProcWakelocks(
1016 byte[] wlBuffer, int len) {
1017 String name;
1018 int count;
1019 long totalTime;
1020 int startIndex, endIndex;
1021 int numUpdatedWlNames = 0;
1022
1023 // Advance past the first line.
1024 int i;
1025 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1026 startIndex = endIndex = i + 1;
1027
1028 synchronized(this) {
1029 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001030
Evan Millarc64edde2009-04-18 12:26:32 -07001031 sKernelWakelockUpdateVersion++;
1032 while (endIndex < len) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001033 for (endIndex=startIndex;
1034 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
Evan Millarc64edde2009-04-18 12:26:32 -07001035 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001036 endIndex++; // endIndex is an exclusive upper bound.
1037 // Don't go over the end of the buffer, Process.parseProcLine might
1038 // write to wlBuffer[endIndex]
1039 if (endIndex >= (len - 1) ) {
1040 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -07001041 }
Evan Millarc64edde2009-04-18 12:26:32 -07001042
1043 String[] nameStringArray = mProcWakelocksName;
1044 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001045 // Stomp out any bad characters since this is from a circular buffer
1046 // A corruption is seen sometimes that results in the vm crashing
1047 // This should prevent crashes and the line will probably fail to parse
1048 for (int j = startIndex; j < endIndex; j++) {
1049 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1050 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001051 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
1052 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001053
Evan Millarc64edde2009-04-18 12:26:32 -07001054 name = nameStringArray[0];
1055 count = (int) wlData[1];
1056 // convert nanoseconds to microseconds with rounding.
1057 totalTime = (wlData[2] + 500) / 1000;
1058
Amith Yamasani53b707b2009-09-30 11:05:30 -07001059 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001060 if (!m.containsKey(name)) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001061 m.put(name, new KernelWakelockStats(count, totalTime,
Evan Millarc64edde2009-04-18 12:26:32 -07001062 sKernelWakelockUpdateVersion));
1063 numUpdatedWlNames++;
1064 } else {
1065 KernelWakelockStats kwlStats = m.get(name);
1066 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1067 kwlStats.mCount += count;
1068 kwlStats.mTotalTime += totalTime;
1069 } else {
1070 kwlStats.mCount = count;
1071 kwlStats.mTotalTime = totalTime;
1072 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1073 numUpdatedWlNames++;
1074 }
1075 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001076 }
Evan Millarc64edde2009-04-18 12:26:32 -07001077 startIndex = endIndex;
1078 }
1079
1080 if (m.size() != numUpdatedWlNames) {
1081 // Don't report old data.
1082 Iterator<KernelWakelockStats> itr = m.values().iterator();
1083 while (itr.hasNext()) {
1084 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1085 itr.remove();
1086 }
1087 }
1088 }
1089 return m;
1090 }
1091 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001092
Evan Millarc64edde2009-04-18 12:26:32 -07001093 private class KernelWakelockStats {
1094 public int mCount;
1095 public long mTotalTime;
1096 public int mVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001097
Evan Millarc64edde2009-04-18 12:26:32 -07001098 KernelWakelockStats(int count, long totalTime, int version) {
1099 mCount = count;
1100 mTotalTime = totalTime;
1101 mVersion = version;
1102 }
1103 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001104
Evan Millarc64edde2009-04-18 12:26:32 -07001105 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001106 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001107 * doesn't already exist.
1108 */
1109 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1110 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1111 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001112 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07001113 true /* track reported values */);
1114 mKernelWakelockStats.put(name, kwlt);
1115 }
1116 return kwlt;
1117 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001118
1119 private void doDataPlug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001120 dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED];
1121 dataTransfer[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001122 }
1123
1124 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001125 dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001126 }
1127
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001128 /**
1129 * Radio uptime in microseconds when transferring data. This value is very approximate.
1130 * @return
1131 */
1132 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001133 try {
1134 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
1135 if (!awakeTimeFile.exists()) return 0;
1136 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
1137 String line = br.readLine();
1138 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001139 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001140 } catch (NumberFormatException nfe) {
1141 // Nothing
1142 } catch (IOException ioe) {
1143 // Nothing
1144 }
1145 return 0;
1146 }
1147
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001148 /**
1149 * @deprecated use getRadioDataUptime
1150 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001151 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001152 return getRadioDataUptime() / 1000;
1153 }
1154
1155 /**
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001156 * Returns the duration that the cell radio was up for data transfers.
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001157 */
1158 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001159 if (mRadioDataStart == -1) {
1160 return mRadioDataUptime;
1161 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001162 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001163 }
1164 }
1165
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001166 private int getCurrentBluetoothPingCount() {
1167 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001168 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1169 if (deviceList.size() > 0) {
1170 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001171 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001172 }
1173 return -1;
1174 }
1175
1176 public int getBluetoothPingCount() {
1177 if (mBluetoothPingStart == -1) {
1178 return mBluetoothPingCount;
1179 } else if (mBtHeadset != null) {
1180 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1181 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001182 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001183 }
1184
1185 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001186 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1187 mBluetoothPingStart = getCurrentBluetoothPingCount();
1188 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001189 mBtHeadset = headset;
1190 }
1191
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001192 int mChangedStates = 0;
1193
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001194 void addHistoryRecordLocked(long curTime) {
1195 if (!mHaveBatteryLevel || !mRecordingHistory) {
1196 return;
1197 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001198
1199 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001200 // and no states have since the last recorded entry changed and
1201 // are now resetting back to their original value, then just collapse
1202 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001203 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001204 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000)
1205 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001206 // If the current is the same as the one before, then we no
1207 // longer need the entry.
1208 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
1209 && mHistoryLastEnd.same(mHistoryCur)) {
1210 mHistoryLastEnd.next = null;
1211 mHistoryEnd.next = mHistoryCache;
1212 mHistoryCache = mHistoryEnd;
1213 mHistoryEnd = mHistoryLastEnd;
1214 mHistoryLastEnd = null;
1215 } else {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001216 mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001217 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
1218 }
1219 return;
1220 }
1221
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001222 mChangedStates = 0;
1223
1224 if (mNumHistoryItems == MAX_HISTORY_ITEMS
1225 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001226 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
1227 }
1228
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001229 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
1230 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001231 // record changes to the battery level and the most interesting states.
1232 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001233 // record changes to the battery level.
1234 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001235 == mHistoryCur.batteryLevel &&
1236 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
1237 || ((mHistoryEnd.states^mHistoryCur.states)
1238 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001239 return;
1240 }
1241 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001242
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001243 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
1244 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001245
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001246 void addHistoryRecordLocked(long curTime, byte cmd) {
1247 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001248 if (rec != null) {
1249 mHistoryCache = rec.next;
1250 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001251 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001252 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001253 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001254
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001255 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001256 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001257
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001258 void addHistoryRecordLocked(HistoryItem rec) {
1259 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001260 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001261 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001262 if (mHistoryEnd != null) {
1263 mHistoryEnd.next = rec;
1264 mHistoryEnd = rec;
1265 } else {
1266 mHistory = mHistoryEnd = rec;
1267 }
1268 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001269
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001270 void clearHistoryLocked() {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001271 if (mHistory != null) {
1272 mHistoryEnd.next = mHistoryCache;
1273 mHistoryCache = mHistory;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001274 mHistory = mHistoryLastEnd = mHistoryEnd = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001275 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001276 mNumHistoryItems = 0;
1277 mHistoryBaseTime = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001278 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001279
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001280 public void doUnplugLocked(long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1282 Uid u = mUidStats.valueAt(iu);
Ken Shirriff1719a392009-12-07 15:57:35 -08001283 u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid);
1284 u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1286 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1287 }
1288 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1289 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
1290 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001291 // Track total mobile data
Ken Shirriff1719a392009-12-07 15:57:35 -08001292 doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1293 doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1294 doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1295 doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001296 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001297 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001298 mRadioDataUptime = 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001299 // Track bt headset ping count
1300 mBluetoothPingStart = getCurrentBluetoothPingCount();
1301 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001303
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001304 public void doPlugLocked(long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1306 Uid u = mUidStats.valueAt(iu);
1307 if (u.mStartedTcpBytesReceived >= 0) {
1308 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1309 u.mStartedTcpBytesReceived = -1;
1310 }
1311 if (u.mStartedTcpBytesSent >= 0) {
1312 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1313 u.mStartedTcpBytesSent = -1;
1314 }
1315 }
1316 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1317 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
1318 }
Ken Shirriff1719a392009-12-07 15:57:35 -08001319 doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1320 doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1321 doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1322 doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001323 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001324 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001325 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001326
1327 // Track bt headset ping count
1328 mBluetoothPingCount = getBluetoothPingCount();
1329 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001331
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001332 int mWakeLockNesting;
1333
1334 public void noteStartWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001335 if (type == WAKE_TYPE_PARTIAL) {
1336 // Only care about partial wake locks, since full wake locks
1337 // will be canceled when the user puts the screen to sleep.
1338 if (mWakeLockNesting == 0) {
1339 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
1340 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
1341 + Integer.toHexString(mHistoryCur.states));
1342 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1343 }
1344 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001345 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001346 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001347 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1348 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1349 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1350 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001351 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
1352 }
1353 }
1354
1355 public void noteStopWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001356 if (type == WAKE_TYPE_PARTIAL) {
1357 mWakeLockNesting--;
1358 if (mWakeLockNesting == 0) {
1359 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
1360 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
1361 + Integer.toHexString(mHistoryCur.states));
1362 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1363 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001364 }
1365 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001366 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1367 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1368 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1369 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001370 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
1371 }
1372 }
1373
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001374 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1375 int N = ws.size();
1376 for (int i=0; i<N; i++) {
1377 noteStartWakeLocked(ws.get(i), pid, name, type);
1378 }
1379 }
1380
1381 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1382 int N = ws.size();
1383 for (int i=0; i<N; i++) {
1384 noteStopWakeLocked(ws.get(i), pid, name, type);
1385 }
1386 }
1387
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001388 public int startAddingCpuLocked() {
1389 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
1390
1391 if (mScreenOn) {
1392 return 0;
1393 }
1394
1395 final int N = mPartialTimers.size();
1396 if (N == 0) {
1397 mLastPartialTimers.clear();
1398 return 0;
1399 }
1400
1401 // How many timers should consume CPU? Only want to include ones
1402 // that have already been in the list.
1403 for (int i=0; i<N; i++) {
1404 StopwatchTimer st = mPartialTimers.get(i);
1405 if (st.mInList) {
1406 Uid uid = st.mUid;
1407 // We don't include the system UID, because it so often
1408 // holds wake locks at one request or another of an app.
1409 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1410 return 50;
1411 }
1412 }
1413 }
1414
1415 return 0;
1416 }
1417
1418 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
1419 final int N = mPartialTimers.size();
1420 if (perc != 0) {
1421 int num = 0;
1422 for (int i=0; i<N; i++) {
1423 StopwatchTimer st = mPartialTimers.get(i);
1424 if (st.mInList) {
1425 Uid uid = st.mUid;
1426 // We don't include the system UID, because it so often
1427 // holds wake locks at one request or another of an app.
1428 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1429 num++;
1430 }
1431 }
1432 }
1433 if (num != 0) {
1434 for (int i=0; i<N; i++) {
1435 StopwatchTimer st = mPartialTimers.get(i);
1436 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001437 Uid uid = st.mUid;
1438 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07001439 int myUTime = utime/num;
1440 int mySTime = stime/num;
1441 utime -= myUTime;
1442 stime -= mySTime;
1443 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001444 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
1445 proc.addCpuTimeLocked(myUTime, mySTime);
1446 proc.addSpeedStepTimes(cpuSpeedTimes);
1447 }
1448 }
1449 }
1450 }
1451
1452 // Just in case, collect any lost CPU time.
1453 if (utime != 0 || stime != 0) {
1454 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
1455 if (uid != null) {
1456 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
1457 proc.addCpuTimeLocked(utime, stime);
1458 proc.addSpeedStepTimes(cpuSpeedTimes);
1459 }
1460 }
1461 }
1462
1463 final int NL = mLastPartialTimers.size();
1464 boolean diff = N != NL;
1465 for (int i=0; i<NL && !diff; i++) {
1466 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
1467 }
1468 if (!diff) {
1469 for (int i=0; i<NL; i++) {
1470 mPartialTimers.get(i).mInList = true;
1471 }
1472 return;
1473 }
1474
1475 for (int i=0; i<NL; i++) {
1476 mLastPartialTimers.get(i).mInList = false;
1477 }
1478 mLastPartialTimers.clear();
1479 for (int i=0; i<N; i++) {
1480 StopwatchTimer st = mPartialTimers.get(i);
1481 st.mInList = true;
1482 mLastPartialTimers.add(st);
1483 }
1484 }
1485
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001486 public void noteProcessDiedLocked(int uid, int pid) {
1487 Uid u = mUidStats.get(uid);
1488 if (u != null) {
1489 u.mPids.remove(pid);
1490 }
1491 }
1492
1493 public long getProcessWakeTime(int uid, int pid, long realtime) {
1494 Uid u = mUidStats.get(uid);
1495 if (u != null) {
1496 Uid.Pid p = u.mPids.get(pid);
1497 if (p != null) {
1498 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
1499 }
1500 }
1501 return 0;
1502 }
1503
1504 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
1505 Uid u = mUidStats.get(uid);
1506 if (u != null) {
1507 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
1508 }
1509 }
1510
Dianne Hackborn287952c2010-09-22 22:34:31 -07001511 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
1512 Uid u = mUidStats.get(uid);
1513 if (u != null) {
1514 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
1515 }
1516 }
1517
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001518 int mSensorNesting;
1519
1520 public void noteStartSensorLocked(int uid, int sensor) {
1521 if (mSensorNesting == 0) {
1522 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
1523 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
1524 + Integer.toHexString(mHistoryCur.states));
1525 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1526 }
1527 mSensorNesting++;
1528 getUidStatsLocked(uid).noteStartSensor(sensor);
1529 }
1530
1531 public void noteStopSensorLocked(int uid, int sensor) {
1532 mSensorNesting--;
1533 if (mSensorNesting == 0) {
1534 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
1535 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
1536 + Integer.toHexString(mHistoryCur.states));
1537 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1538 }
1539 getUidStatsLocked(uid).noteStopSensor(sensor);
1540 }
1541
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001542 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001543
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001544 public void noteStartGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001545 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001546 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001547 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
1548 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001549 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001550 }
1551 mGpsNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001552 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001554
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001555 public void noteStopGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001556 mGpsNesting--;
1557 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001558 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001559 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
1560 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001561 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001562 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001563 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 public void noteScreenOnLocked() {
1567 if (!mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001568 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001569 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
1570 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001571 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 mScreenOn = true;
1573 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001574 if (mScreenBrightnessBin >= 0) {
1575 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1576 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001577
1578 // Fake a wake lock, so we consider the device waked as long
1579 // as the screen is on.
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001580 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001581
1582 // Update discharge amounts.
1583 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001584 updateDischargeScreenLevelsLocked(false, true);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 }
1587 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 public void noteScreenOffLocked() {
1590 if (mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001591 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001592 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
1593 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001594 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 mScreenOn = false;
1596 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001597 if (mScreenBrightnessBin >= 0) {
1598 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1599 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001600
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001601 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001602
1603 // Update discharge amounts.
1604 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001605 updateDischargeScreenLevelsLocked(true, false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001606 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001607 }
1608 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001609
Dianne Hackborn617f8772009-03-31 15:04:46 -07001610 public void noteScreenBrightnessLocked(int brightness) {
1611 // Bin the brightness.
1612 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1613 if (bin < 0) bin = 0;
1614 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1615 if (mScreenBrightnessBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001616 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
1617 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001618 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
1619 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001620 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001621 if (mScreenOn) {
1622 if (mScreenBrightnessBin >= 0) {
1623 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1624 }
1625 mScreenBrightnessTimer[bin].startRunningLocked(this);
1626 }
1627 mScreenBrightnessBin = bin;
1628 }
1629 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001630
Christopher Tate4cee7252010-03-19 14:50:40 -07001631 public void noteInputEventAtomic() {
1632 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001633 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001634
Dianne Hackborn617f8772009-03-31 15:04:46 -07001635 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001636 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001638
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 public void notePhoneOnLocked() {
1640 if (!mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001641 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001642 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
1643 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001644 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 mPhoneOn = true;
1646 mPhoneOnTimer.startRunningLocked(this);
1647 }
1648 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001650 public void notePhoneOffLocked() {
1651 if (mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001652 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001653 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
1654 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001655 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 mPhoneOn = false;
1657 mPhoneOnTimer.stopRunningLocked(this);
1658 }
1659 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001660
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001661 void stopAllSignalStrengthTimersLocked(int except) {
Wink Saville52840902011-02-18 12:40:47 -08001662 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001663 if (i == except) {
1664 continue;
1665 }
1666 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1667 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
1668 }
1669 }
1670 }
1671
Dianne Hackborne4a59512010-12-07 11:08:07 -08001672 private int fixPhoneServiceState(int state, int signalBin) {
1673 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
1674 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1675 // to infer that we are scanning from other data.
1676 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08001677 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001678 state = ServiceState.STATE_IN_SERVICE;
1679 }
1680 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001681
Dianne Hackborne4a59512010-12-07 11:08:07 -08001682 return state;
1683 }
1684
1685 private void updateAllPhoneStateLocked(int state, int simState, int bin) {
1686 boolean scanning = false;
1687 boolean newHistory = false;
1688
1689 mPhoneServiceStateRaw = state;
1690 mPhoneSimStateRaw = simState;
1691 mPhoneSignalStrengthBinRaw = bin;
1692
1693 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
1694 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1695 // to infer that we are scanning from other data.
1696 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08001697 && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001698 state = ServiceState.STATE_IN_SERVICE;
1699 }
1700 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001701
1702 // If the phone is powered off, stop all timers.
1703 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001704 bin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001705
Dianne Hackborne4a59512010-12-07 11:08:07 -08001706 // If we are in service, make sure the correct signal string timer is running.
1707 } else if (state == ServiceState.STATE_IN_SERVICE) {
1708 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001709
1710 // If we're out of service, we are in the lowest signal strength
1711 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07001712 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001713 scanning = true;
Wink Saville52840902011-02-18 12:40:47 -08001714 bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001715 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001716 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001717 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001718 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
1719 + Integer.toHexString(mHistoryCur.states));
Amith Yamasanif37447b2009-10-08 18:28:01 -07001720 mPhoneSignalScanningTimer.startRunningLocked(this);
1721 }
1722 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001723
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001724 if (!scanning) {
1725 // If we are no longer scanning, then stop the scanning timer.
1726 if (mPhoneSignalScanningTimer.isRunningLocked()) {
1727 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
1728 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
1729 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001730 newHistory = true;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001731 mPhoneSignalScanningTimer.stopRunningLocked(this);
1732 }
1733 }
1734
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001735 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001736 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
1737 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08001738 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001739 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001740 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001741 mPhoneServiceState = state;
1742 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001743
1744 if (mPhoneSignalStrengthBin != bin) {
1745 if (mPhoneSignalStrengthBin >= 0) {
1746 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1747 }
1748 if (bin >= 0) {
1749 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1750 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1751 }
1752 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
1753 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
1754 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
1755 + Integer.toHexString(mHistoryCur.states));
1756 newHistory = true;
1757 } else {
1758 stopAllSignalStrengthTimersLocked(-1);
1759 }
1760 mPhoneSignalStrengthBin = bin;
1761 }
1762
1763 if (newHistory) {
1764 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1765 }
1766 }
1767
1768 /**
1769 * Telephony stack updates the phone state.
1770 * @param state phone state from ServiceState.getState()
1771 */
1772 public void notePhoneStateLocked(int state, int simState) {
1773 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001774 }
1775
Wink Savillee9b06d72009-05-18 21:47:50 -07001776 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001777 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08001778 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08001779 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001780 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001781
Dianne Hackborn627bba72009-03-24 22:32:56 -07001782 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1783 int bin = DATA_CONNECTION_NONE;
1784 if (hasData) {
1785 switch (dataType) {
1786 case TelephonyManager.NETWORK_TYPE_EDGE:
1787 bin = DATA_CONNECTION_EDGE;
1788 break;
1789 case TelephonyManager.NETWORK_TYPE_GPRS:
1790 bin = DATA_CONNECTION_GPRS;
1791 break;
1792 case TelephonyManager.NETWORK_TYPE_UMTS:
1793 bin = DATA_CONNECTION_UMTS;
1794 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001795 case TelephonyManager.NETWORK_TYPE_CDMA:
1796 bin = DATA_CONNECTION_CDMA;
1797 break;
1798 case TelephonyManager.NETWORK_TYPE_EVDO_0:
1799 bin = DATA_CONNECTION_EVDO_0;
1800 break;
1801 case TelephonyManager.NETWORK_TYPE_EVDO_A:
1802 bin = DATA_CONNECTION_EVDO_A;
1803 break;
1804 case TelephonyManager.NETWORK_TYPE_1xRTT:
1805 bin = DATA_CONNECTION_1xRTT;
1806 break;
1807 case TelephonyManager.NETWORK_TYPE_HSDPA:
1808 bin = DATA_CONNECTION_HSDPA;
1809 break;
1810 case TelephonyManager.NETWORK_TYPE_HSUPA:
1811 bin = DATA_CONNECTION_HSUPA;
1812 break;
1813 case TelephonyManager.NETWORK_TYPE_HSPA:
1814 bin = DATA_CONNECTION_HSPA;
1815 break;
1816 case TelephonyManager.NETWORK_TYPE_IDEN:
1817 bin = DATA_CONNECTION_IDEN;
1818 break;
1819 case TelephonyManager.NETWORK_TYPE_EVDO_B:
1820 bin = DATA_CONNECTION_EVDO_B;
1821 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07001822 case TelephonyManager.NETWORK_TYPE_LTE:
1823 bin = DATA_CONNECTION_LTE;
1824 break;
1825 case TelephonyManager.NETWORK_TYPE_EHRPD:
1826 bin = DATA_CONNECTION_EHRPD;
1827 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001828 default:
1829 bin = DATA_CONNECTION_OTHER;
1830 break;
1831 }
1832 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001833 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001834 if (mPhoneDataConnectionType != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001835 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
1836 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001837 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
1838 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001839 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07001840 if (mPhoneDataConnectionType >= 0) {
1841 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
1842 }
1843 mPhoneDataConnectionType = bin;
1844 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
1845 }
1846 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001847
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001848 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07001849 if (!mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001850 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001851 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
1852 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001853 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001854 mWifiOn = true;
1855 mWifiOnTimer.startRunningLocked(this);
1856 }
1857 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001858
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001859 public void noteWifiOffLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07001860 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001861 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001862 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
1863 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001864 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001865 mWifiOn = false;
1866 mWifiOnTimer.stopRunningLocked(this);
1867 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001868 if (mWifiOnUid >= 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001869 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001870 mWifiOnUid = -1;
1871 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001872 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001873
1874 public void noteAudioOnLocked(int uid) {
1875 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001876 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001877 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
1878 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001879 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001880 mAudioOn = true;
1881 mAudioOnTimer.startRunningLocked(this);
1882 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001883 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001884 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001885
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001886 public void noteAudioOffLocked(int uid) {
1887 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001888 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001889 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
1890 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001891 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001892 mAudioOn = false;
1893 mAudioOnTimer.stopRunningLocked(this);
1894 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001895 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001896 }
1897
1898 public void noteVideoOnLocked(int uid) {
1899 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001900 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001901 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
1902 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001903 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001904 mVideoOn = true;
1905 mVideoOnTimer.startRunningLocked(this);
1906 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001907 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001908 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001909
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001910 public void noteVideoOffLocked(int uid) {
1911 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001912 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001913 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
1914 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001915 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001916 mVideoOn = false;
1917 mVideoOnTimer.stopRunningLocked(this);
1918 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001919 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001920 }
1921
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001922 public void noteWifiRunningLocked(WorkSource ws) {
1923 if (!mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001924 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001925 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
1926 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001927 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001928 mGlobalWifiRunning = true;
1929 mGlobalWifiRunningTimer.startRunningLocked(this);
1930 int N = ws.size();
1931 for (int i=0; i<N; i++) {
1932 getUidStatsLocked(ws.get(i)).noteWifiRunningLocked();
1933 }
1934 } else {
1935 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001936 }
1937 }
1938
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001939 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
1940 if (mGlobalWifiRunning) {
1941 int N = oldWs.size();
1942 for (int i=0; i<N; i++) {
1943 getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked();
1944 }
1945 N = newWs.size();
1946 for (int i=0; i<N; i++) {
1947 getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked();
1948 }
1949 } else {
1950 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
1951 }
1952 }
1953
1954 public void noteWifiStoppedLocked(WorkSource ws) {
1955 if (mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001956 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001957 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
1958 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001959 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001960 mGlobalWifiRunning = false;
1961 mGlobalWifiRunningTimer.stopRunningLocked(this);
1962 int N = ws.size();
1963 for (int i=0; i<N; i++) {
1964 getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked();
1965 }
1966 } else {
1967 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001968 }
1969 }
1970
The Android Open Source Project10592532009-03-18 17:39:46 -07001971 public void noteBluetoothOnLocked() {
1972 if (!mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001973 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001974 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
1975 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001976 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001977 mBluetoothOn = true;
1978 mBluetoothOnTimer.startRunningLocked(this);
1979 }
1980 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001981
The Android Open Source Project10592532009-03-18 17:39:46 -07001982 public void noteBluetoothOffLocked() {
1983 if (mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001984 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001985 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
1986 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001987 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001988 mBluetoothOn = false;
1989 mBluetoothOnTimer.stopRunningLocked(this);
1990 }
1991 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001992
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001993 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001994
The Android Open Source Project10592532009-03-18 17:39:46 -07001995 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001996 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001997 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001998 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
1999 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002000 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002001 }
2002 mWifiFullLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002003 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002004 }
2005
2006 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002007 mWifiFullLockNesting--;
2008 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002009 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002010 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
2011 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002012 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002013 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002014 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002015 }
2016
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002017 int mWifiScanLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002018
The Android Open Source Project10592532009-03-18 17:39:46 -07002019 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002020 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002021 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002022 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: "
2023 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002024 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002025 }
2026 mWifiScanLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002027 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002028 }
2029
2030 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002031 mWifiScanLockNesting--;
2032 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002033 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002034 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: "
2035 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002036 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002037 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002038 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002039 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002040
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002041 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002042
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002043 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002044 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002045 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002046 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
2047 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002048 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002049 }
2050 mWifiMulticastNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002051 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002052 }
2053
2054 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002055 mWifiMulticastNesting--;
2056 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002057 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002058 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
2059 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002060 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002061 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002062 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002063 }
2064
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002065 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2066 int N = ws.size();
2067 for (int i=0; i<N; i++) {
2068 noteFullWifiLockAcquiredLocked(ws.get(i));
2069 }
2070 }
2071
2072 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
2073 int N = ws.size();
2074 for (int i=0; i<N; i++) {
2075 noteFullWifiLockReleasedLocked(ws.get(i));
2076 }
2077 }
2078
2079 public void noteScanWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2080 int N = ws.size();
2081 for (int i=0; i<N; i++) {
2082 noteScanWifiLockAcquiredLocked(ws.get(i));
2083 }
2084 }
2085
2086 public void noteScanWifiLockReleasedFromSourceLocked(WorkSource ws) {
2087 int N = ws.size();
2088 for (int i=0; i<N; i++) {
2089 noteScanWifiLockReleasedLocked(ws.get(i));
2090 }
2091 }
2092
2093 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
2094 int N = ws.size();
2095 for (int i=0; i<N; i++) {
2096 noteWifiMulticastEnabledLocked(ws.get(i));
2097 }
2098 }
2099
2100 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
2101 int N = ws.size();
2102 for (int i=0; i<N; i++) {
2103 noteWifiMulticastDisabledLocked(ws.get(i));
2104 }
2105 }
2106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002107 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002108 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002110
Dianne Hackborn617f8772009-03-31 15:04:46 -07002111 @Override public long getScreenBrightnessTime(int brightnessBin,
2112 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002113 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07002114 batteryRealtime, which);
2115 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002116
Dianne Hackborn617f8772009-03-31 15:04:46 -07002117 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002118 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002119 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002121 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002122 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002123 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002124
Dianne Hackborn627bba72009-03-24 22:32:56 -07002125 @Override public long getPhoneSignalStrengthTime(int strengthBin,
2126 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002127 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002128 batteryRealtime, which);
2129 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002130
2131 @Override public long getPhoneSignalScanningTime(
2132 long batteryRealtime, int which) {
2133 return mPhoneSignalScanningTimer.getTotalTimeLocked(
2134 batteryRealtime, which);
2135 }
2136
Dianne Hackborn617f8772009-03-31 15:04:46 -07002137 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002138 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002139 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002140
Dianne Hackborn627bba72009-03-24 22:32:56 -07002141 @Override public long getPhoneDataConnectionTime(int dataType,
2142 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002143 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002144 batteryRealtime, which);
2145 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002146
Dianne Hackborn617f8772009-03-31 15:04:46 -07002147 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002148 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002149 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002150
The Android Open Source Project10592532009-03-18 17:39:46 -07002151 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002152 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002153 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002154
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002155 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) {
2156 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002157 }
2158
The Android Open Source Project10592532009-03-18 17:39:46 -07002159 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002160 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002161 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163 @Override public boolean getIsOnBattery() {
2164 return mOnBattery;
2165 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
2168 return mUidStats;
2169 }
2170
2171 /**
2172 * The statistics associated with a particular uid.
2173 */
2174 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002176 final int mUid;
2177 long mLoadedTcpBytesReceived;
2178 long mLoadedTcpBytesSent;
2179 long mCurrentTcpBytesReceived;
2180 long mCurrentTcpBytesSent;
2181 long mTcpBytesReceivedAtLastUnplug;
2182 long mTcpBytesSentAtLastUnplug;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002184 // These are not saved/restored when parcelling, since we want
2185 // to return from the parcel with a snapshot of the state.
2186 long mStartedTcpBytesReceived = -1;
2187 long mStartedTcpBytesSent = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002188
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002189 boolean mWifiRunning;
2190 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002191
The Android Open Source Project10592532009-03-18 17:39:46 -07002192 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002193 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002194
The Android Open Source Project10592532009-03-18 17:39:46 -07002195 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002196 StopwatchTimer mScanWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002197
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002198 boolean mWifiMulticastEnabled;
2199 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002200
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002201 boolean mAudioTurnedOn;
2202 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002203
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002204 boolean mVideoTurnedOn;
2205 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002206
Dianne Hackborn617f8772009-03-31 15:04:46 -07002207 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 /**
2210 * The statistics we have collected for this uid's wake locks.
2211 */
2212 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
2213
2214 /**
2215 * The statistics we have collected for this uid's sensor activations.
2216 */
2217 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
2218
2219 /**
2220 * The statistics we have collected for this uid's processes.
2221 */
2222 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
2223
2224 /**
2225 * The statistics we have collected for this uid's processes.
2226 */
2227 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002228
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002229 /**
2230 * The transient wake stats we have collected for this uid's pids.
2231 */
2232 final SparseArray<Pid> mPids = new SparseArray<Pid>();
2233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002234 public Uid(int uid) {
2235 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002236 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2237 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002238 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002239 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002240 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002241 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002242 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002243 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002244 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
2245 null, mUnpluggables);
2246 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
2247 null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002248 }
2249
2250 @Override
2251 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
2252 return mWakelockStats;
2253 }
2254
2255 @Override
2256 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
2257 return mSensorStats;
2258 }
2259
2260 @Override
2261 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
2262 return mProcessStats;
2263 }
2264
2265 @Override
2266 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
2267 return mPackageStats;
2268 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002269
2270 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002271 public int getUid() {
2272 return mUid;
2273 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002274
2275 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 public long getTcpBytesReceived(int which) {
2277 if (which == STATS_LAST) {
2278 return mLoadedTcpBytesReceived;
2279 } else {
2280 long current = computeCurrentTcpBytesReceived();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002281 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002282 current -= mTcpBytesReceivedAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002283 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 current += mLoadedTcpBytesReceived;
2285 }
2286 return current;
2287 }
2288 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 public long computeCurrentTcpBytesReceived() {
2291 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08002292 ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002294
2295 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 public long getTcpBytesSent(int which) {
2297 if (which == STATS_LAST) {
2298 return mLoadedTcpBytesSent;
2299 } else {
2300 long current = computeCurrentTcpBytesSent();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002301 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 current -= mTcpBytesSentAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002303 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002304 current += mLoadedTcpBytesSent;
2305 }
2306 return current;
2307 }
2308 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002309
The Android Open Source Project10592532009-03-18 17:39:46 -07002310 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002311 public void noteWifiRunningLocked() {
2312 if (!mWifiRunning) {
2313 mWifiRunning = true;
2314 if (mWifiRunningTimer == null) {
2315 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2316 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002317 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002318 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002319 }
2320 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002321
Dianne Hackborn617f8772009-03-31 15:04:46 -07002322 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002323 public void noteWifiStoppedLocked() {
2324 if (mWifiRunning) {
2325 mWifiRunning = false;
2326 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002327 }
2328 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002329
Dianne Hackborn617f8772009-03-31 15:04:46 -07002330 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002331 public void noteFullWifiLockAcquiredLocked() {
2332 if (!mFullWifiLockOut) {
2333 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002334 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002335 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002336 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002337 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002338 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2339 }
2340 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002341
The Android Open Source Project10592532009-03-18 17:39:46 -07002342 @Override
2343 public void noteFullWifiLockReleasedLocked() {
2344 if (mFullWifiLockOut) {
2345 mFullWifiLockOut = false;
2346 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2347 }
2348 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002349
The Android Open Source Project10592532009-03-18 17:39:46 -07002350 @Override
2351 public void noteScanWifiLockAcquiredLocked() {
2352 if (!mScanWifiLockOut) {
2353 mScanWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002354 if (mScanWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002355 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002356 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002357 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002358 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2359 }
2360 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002361
The Android Open Source Project10592532009-03-18 17:39:46 -07002362 @Override
2363 public void noteScanWifiLockReleasedLocked() {
2364 if (mScanWifiLockOut) {
2365 mScanWifiLockOut = false;
2366 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2367 }
2368 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002369
2370 @Override
2371 public void noteWifiMulticastEnabledLocked() {
2372 if (!mWifiMulticastEnabled) {
2373 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002374 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002375 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002376 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002377 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002378 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
2379 }
2380 }
2381
2382 @Override
2383 public void noteWifiMulticastDisabledLocked() {
2384 if (mWifiMulticastEnabled) {
2385 mWifiMulticastEnabled = false;
2386 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
2387 }
2388 }
2389
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002390 @Override
2391 public void noteAudioTurnedOnLocked() {
2392 if (!mAudioTurnedOn) {
2393 mAudioTurnedOn = true;
2394 if (mAudioTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002395 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002396 null, mUnpluggables);
2397 }
2398 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2399 }
2400 }
2401
2402 @Override
2403 public void noteAudioTurnedOffLocked() {
2404 if (mAudioTurnedOn) {
2405 mAudioTurnedOn = false;
2406 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2407 }
2408 }
2409
2410 @Override
2411 public void noteVideoTurnedOnLocked() {
2412 if (!mVideoTurnedOn) {
2413 mVideoTurnedOn = true;
2414 if (mVideoTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002415 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002416 null, mUnpluggables);
2417 }
2418 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2419 }
2420 }
2421
2422 @Override
2423 public void noteVideoTurnedOffLocked() {
2424 if (mVideoTurnedOn) {
2425 mVideoTurnedOn = false;
2426 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2427 }
2428 }
2429
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002430 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002431 public long getWifiRunningTime(long batteryRealtime, int which) {
2432 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002433 return 0;
2434 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002435 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002436 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002437
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002438 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002439 public long getFullWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002440 if (mFullWifiLockTimer == null) {
2441 return 0;
2442 }
Evan Millarc64edde2009-04-18 12:26:32 -07002443 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002444 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002445
2446 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002447 public long getScanWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002448 if (mScanWifiLockTimer == null) {
2449 return 0;
2450 }
Evan Millarc64edde2009-04-18 12:26:32 -07002451 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002452 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002453
2454 @Override
2455 public long getWifiMulticastTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002456 if (mWifiMulticastTimer == null) {
2457 return 0;
2458 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002459 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
2460 which);
2461 }
2462
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002463 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002464 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
2465 if (mAudioTurnedOnTimer == null) {
2466 return 0;
2467 }
2468 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2469 }
2470
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002471 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002472 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
2473 if (mVideoTurnedOnTimer == null) {
2474 return 0;
2475 }
2476 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2477 }
2478
Dianne Hackborn617f8772009-03-31 15:04:46 -07002479 @Override
2480 public void noteUserActivityLocked(int type) {
2481 if (mUserActivityCounters == null) {
2482 initUserActivityLocked();
2483 }
2484 if (type < 0) type = 0;
2485 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
Christopher Tate4cee7252010-03-19 14:50:40 -07002486 mUserActivityCounters[type].stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002487 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002488
Dianne Hackborn617f8772009-03-31 15:04:46 -07002489 @Override
2490 public boolean hasUserActivity() {
2491 return mUserActivityCounters != null;
2492 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002493
Dianne Hackborn617f8772009-03-31 15:04:46 -07002494 @Override
2495 public int getUserActivityCount(int type, int which) {
2496 if (mUserActivityCounters == null) {
2497 return 0;
2498 }
Evan Millarc64edde2009-04-18 12:26:32 -07002499 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002500 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002501
Dianne Hackborn617f8772009-03-31 15:04:46 -07002502 void initUserActivityLocked() {
2503 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2504 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2505 mUserActivityCounters[i] = new Counter(mUnpluggables);
2506 }
2507 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 public long computeCurrentTcpBytesSent() {
2510 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08002511 ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002512 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002513
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002514 /**
2515 * Clear all stats for this uid. Returns true if the uid is completely
2516 * inactive so can be dropped.
2517 */
2518 boolean reset() {
2519 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002520
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002521 if (mWifiRunningTimer != null) {
2522 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false);
2523 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002524 }
2525 if (mFullWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002526 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002527 active |= mFullWifiLockOut;
2528 }
2529 if (mScanWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002530 active |= !mScanWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002531 active |= mScanWifiLockOut;
2532 }
2533 if (mWifiMulticastTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002534 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002535 active |= mWifiMulticastEnabled;
2536 }
2537 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002538 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002539 active |= mAudioTurnedOn;
2540 }
2541 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002542 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002543 active |= mVideoTurnedOn;
2544 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002545
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002546 mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0;
2547 mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002548
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002549 if (mUserActivityCounters != null) {
2550 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2551 mUserActivityCounters[i].reset(false);
2552 }
2553 }
2554
2555 if (mWakelockStats.size() > 0) {
2556 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
2557 while (it.hasNext()) {
2558 Map.Entry<String, Wakelock> wakelockEntry = it.next();
2559 Wakelock wl = wakelockEntry.getValue();
2560 if (wl.reset()) {
2561 it.remove();
2562 } else {
2563 active = true;
2564 }
2565 }
2566 }
2567 if (mSensorStats.size() > 0) {
2568 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
2569 while (it.hasNext()) {
2570 Map.Entry<Integer, Sensor> sensorEntry = it.next();
2571 Sensor s = sensorEntry.getValue();
2572 if (s.reset()) {
2573 it.remove();
2574 } else {
2575 active = true;
2576 }
2577 }
2578 }
2579 if (mProcessStats.size() > 0) {
2580 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
2581 while (it.hasNext()) {
2582 Map.Entry<String, Proc> procEntry = it.next();
2583 procEntry.getValue().detach();
2584 }
2585 mProcessStats.clear();
2586 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002587 if (mPids.size() > 0) {
2588 for (int i=0; !active && i<mPids.size(); i++) {
2589 Pid pid = mPids.valueAt(i);
2590 if (pid.mWakeStart != 0) {
2591 active = true;
2592 }
2593 }
2594 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002595 if (mPackageStats.size() > 0) {
2596 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
2597 while (it.hasNext()) {
2598 Map.Entry<String, Pkg> pkgEntry = it.next();
2599 Pkg p = pkgEntry.getValue();
2600 p.detach();
2601 if (p.mServiceStats.size() > 0) {
2602 Iterator<Map.Entry<String, Pkg.Serv>> it2
2603 = p.mServiceStats.entrySet().iterator();
2604 while (it2.hasNext()) {
2605 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
2606 servEntry.getValue().detach();
2607 }
2608 }
2609 }
2610 mPackageStats.clear();
2611 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002612
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002613 mPids.clear();
2614
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002615 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002616 if (mWifiRunningTimer != null) {
2617 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002618 }
2619 if (mFullWifiLockTimer != null) {
2620 mFullWifiLockTimer.detach();
2621 }
2622 if (mScanWifiLockTimer != null) {
2623 mScanWifiLockTimer.detach();
2624 }
2625 if (mWifiMulticastTimer != null) {
2626 mWifiMulticastTimer.detach();
2627 }
2628 if (mAudioTurnedOnTimer != null) {
2629 mAudioTurnedOnTimer.detach();
2630 }
2631 if (mVideoTurnedOnTimer != null) {
2632 mVideoTurnedOnTimer.detach();
2633 }
2634 if (mUserActivityCounters != null) {
2635 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2636 mUserActivityCounters[i].detach();
2637 }
2638 }
2639 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002640
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002641 return !active;
2642 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2645 out.writeInt(mWakelockStats.size());
2646 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
2647 out.writeString(wakelockEntry.getKey());
2648 Uid.Wakelock wakelock = wakelockEntry.getValue();
2649 wakelock.writeToParcelLocked(out, batteryRealtime);
2650 }
2651
2652 out.writeInt(mSensorStats.size());
2653 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
2654 out.writeInt(sensorEntry.getKey());
2655 Uid.Sensor sensor = sensorEntry.getValue();
2656 sensor.writeToParcelLocked(out, batteryRealtime);
2657 }
2658
2659 out.writeInt(mProcessStats.size());
2660 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
2661 out.writeString(procEntry.getKey());
2662 Uid.Proc proc = procEntry.getValue();
2663 proc.writeToParcelLocked(out);
2664 }
2665
2666 out.writeInt(mPackageStats.size());
2667 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
2668 out.writeString(pkgEntry.getKey());
2669 Uid.Pkg pkg = pkgEntry.getValue();
2670 pkg.writeToParcelLocked(out);
2671 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002673 out.writeLong(mLoadedTcpBytesReceived);
2674 out.writeLong(mLoadedTcpBytesSent);
2675 out.writeLong(computeCurrentTcpBytesReceived());
2676 out.writeLong(computeCurrentTcpBytesSent());
2677 out.writeLong(mTcpBytesReceivedAtLastUnplug);
2678 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002679 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002680 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002681 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002682 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002683 out.writeInt(0);
2684 }
2685 if (mFullWifiLockTimer != null) {
2686 out.writeInt(1);
2687 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
2688 } else {
2689 out.writeInt(0);
2690 }
2691 if (mScanWifiLockTimer != null) {
2692 out.writeInt(1);
2693 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
2694 } else {
2695 out.writeInt(0);
2696 }
2697 if (mWifiMulticastTimer != null) {
2698 out.writeInt(1);
2699 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
2700 } else {
2701 out.writeInt(0);
2702 }
2703 if (mAudioTurnedOnTimer != null) {
2704 out.writeInt(1);
2705 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
2706 } else {
2707 out.writeInt(0);
2708 }
2709 if (mVideoTurnedOnTimer != null) {
2710 out.writeInt(1);
2711 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
2712 } else {
2713 out.writeInt(0);
2714 }
2715 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002716 out.writeInt(1);
2717 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2718 mUserActivityCounters[i].writeToParcel(out);
2719 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002720 } else {
2721 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002722 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002723 }
2724
2725 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2726 int numWakelocks = in.readInt();
2727 mWakelockStats.clear();
2728 for (int j = 0; j < numWakelocks; j++) {
2729 String wakelockName = in.readString();
2730 Uid.Wakelock wakelock = new Wakelock();
2731 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002732 if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) {
2733 // We will just drop some random set of wakelocks if
2734 // the previous run of the system was an older version
2735 // that didn't impose a limit.
2736 mWakelockStats.put(wakelockName, wakelock);
2737 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002738 }
2739
2740 int numSensors = in.readInt();
2741 mSensorStats.clear();
2742 for (int k = 0; k < numSensors; k++) {
2743 int sensorNumber = in.readInt();
2744 Uid.Sensor sensor = new Sensor(sensorNumber);
2745 sensor.readFromParcelLocked(mUnpluggables, in);
2746 mSensorStats.put(sensorNumber, sensor);
2747 }
2748
2749 int numProcs = in.readInt();
2750 mProcessStats.clear();
2751 for (int k = 0; k < numProcs; k++) {
2752 String processName = in.readString();
2753 Uid.Proc proc = new Proc();
2754 proc.readFromParcelLocked(in);
2755 mProcessStats.put(processName, proc);
2756 }
2757
2758 int numPkgs = in.readInt();
2759 mPackageStats.clear();
2760 for (int l = 0; l < numPkgs; l++) {
2761 String packageName = in.readString();
2762 Uid.Pkg pkg = new Pkg();
2763 pkg.readFromParcelLocked(in);
2764 mPackageStats.put(packageName, pkg);
2765 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 mLoadedTcpBytesReceived = in.readLong();
2768 mLoadedTcpBytesSent = in.readLong();
2769 mCurrentTcpBytesReceived = in.readLong();
2770 mCurrentTcpBytesSent = in.readLong();
2771 mTcpBytesReceivedAtLastUnplug = in.readLong();
2772 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002773 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002774 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002775 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2776 mWifiRunningTimers, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002777 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002778 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002779 }
2780 mFullWifiLockOut = false;
2781 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002782 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002783 mFullWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002784 } else {
2785 mFullWifiLockTimer = null;
2786 }
2787 mScanWifiLockOut = false;
2788 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002789 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002790 mScanWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002791 } else {
2792 mScanWifiLockTimer = null;
2793 }
2794 mWifiMulticastEnabled = false;
2795 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002796 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002797 mWifiMulticastTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002798 } else {
2799 mWifiMulticastTimer = null;
2800 }
2801 mAudioTurnedOn = false;
2802 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002803 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002804 null, mUnpluggables, in);
2805 } else {
2806 mAudioTurnedOnTimer = null;
2807 }
2808 mVideoTurnedOn = false;
2809 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002810 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002811 null, mUnpluggables, in);
2812 } else {
2813 mVideoTurnedOnTimer = null;
2814 }
2815 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002816 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2817 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2818 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
2819 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002820 } else {
2821 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07002822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 }
2824
2825 /**
2826 * The statistics associated with a particular wake lock.
2827 */
2828 public final class Wakelock extends BatteryStats.Uid.Wakelock {
2829 /**
2830 * How long (in ms) this uid has been keeping the device partially awake.
2831 */
Evan Millarc64edde2009-04-18 12:26:32 -07002832 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002833
2834 /**
2835 * How long (in ms) this uid has been keeping the device fully awake.
2836 */
Evan Millarc64edde2009-04-18 12:26:32 -07002837 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838
2839 /**
2840 * How long (in ms) this uid has had a window keeping the device awake.
2841 */
Evan Millarc64edde2009-04-18 12:26:32 -07002842 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843
2844 /**
2845 * Reads a possibly null Timer from a Parcel. The timer is associated with the
2846 * proper timer pool from the given BatteryStatsImpl object.
2847 *
2848 * @param in the Parcel to be read from.
2849 * return a new Timer, or null.
2850 */
Evan Millarc64edde2009-04-18 12:26:32 -07002851 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002852 ArrayList<Unpluggable> unpluggables, Parcel in) {
2853 if (in.readInt() == 0) {
2854 return null;
2855 }
2856
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002857 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002858 }
2859
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002860 boolean reset() {
2861 boolean wlactive = false;
2862 if (mTimerFull != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002863 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002864 }
2865 if (mTimerPartial != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002866 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002867 }
2868 if (mTimerWindow != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002869 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002870 }
2871 if (!wlactive) {
2872 if (mTimerFull != null) {
2873 mTimerFull.detach();
2874 mTimerFull = null;
2875 }
2876 if (mTimerPartial != null) {
2877 mTimerPartial.detach();
2878 mTimerPartial = null;
2879 }
2880 if (mTimerWindow != null) {
2881 mTimerWindow.detach();
2882 mTimerWindow = null;
2883 }
2884 }
2885 return !wlactive;
2886 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002888 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2889 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
2890 mPartialTimers, unpluggables, in);
2891 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
2892 mFullTimers, unpluggables, in);
2893 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
2894 mWindowTimers, unpluggables, in);
2895 }
2896
2897 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2898 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
2899 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
2900 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
2901 }
2902
2903 @Override
2904 public Timer getWakeTime(int type) {
2905 switch (type) {
2906 case WAKE_TYPE_FULL: return mTimerFull;
2907 case WAKE_TYPE_PARTIAL: return mTimerPartial;
2908 case WAKE_TYPE_WINDOW: return mTimerWindow;
2909 default: throw new IllegalArgumentException("type = " + type);
2910 }
2911 }
2912 }
2913
2914 public final class Sensor extends BatteryStats.Uid.Sensor {
2915 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07002916 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002918 public Sensor(int handle) {
2919 mHandle = handle;
2920 }
2921
Evan Millarc64edde2009-04-18 12:26:32 -07002922 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923 Parcel in) {
2924 if (in.readInt() == 0) {
2925 return null;
2926 }
2927
Evan Millarc64edde2009-04-18 12:26:32 -07002928 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002929 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002930 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002931 mSensorTimers.put(mHandle, pool);
2932 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002933 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002934 }
2935
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002936 boolean reset() {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002937 if (mTimer.reset(BatteryStatsImpl.this, true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002938 mTimer = null;
2939 return true;
2940 }
2941 return false;
2942 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002944 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2945 mTimer = readTimerFromParcel(unpluggables, in);
2946 }
2947
2948 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2949 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
2950 }
2951
2952 @Override
2953 public Timer getSensorTime() {
2954 return mTimer;
2955 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002956
2957 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 public int getHandle() {
2959 return mHandle;
2960 }
2961 }
2962
2963 /**
2964 * The statistics associated with a particular process.
2965 */
2966 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
2967 /**
2968 * Total time (in 1/100 sec) spent executing in user code.
2969 */
2970 long mUserTime;
2971
2972 /**
2973 * Total time (in 1/100 sec) spent executing in kernel code.
2974 */
2975 long mSystemTime;
2976
2977 /**
2978 * Number of times the process has been started.
2979 */
2980 int mStarts;
2981
2982 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002983 * Amount of time the process was running in the foreground.
2984 */
2985 long mForegroundTime;
2986
2987 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 * The amount of user time loaded from a previous save.
2989 */
2990 long mLoadedUserTime;
2991
2992 /**
2993 * The amount of system time loaded from a previous save.
2994 */
2995 long mLoadedSystemTime;
2996
2997 /**
2998 * The number of times the process has started from a previous save.
2999 */
3000 int mLoadedStarts;
3001
3002 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003003 * The amount of foreground time loaded from a previous save.
3004 */
3005 long mLoadedForegroundTime;
3006
3007 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003008 * The amount of user time loaded from the previous run.
3009 */
3010 long mLastUserTime;
3011
3012 /**
3013 * The amount of system time loaded from the previous run.
3014 */
3015 long mLastSystemTime;
3016
3017 /**
3018 * The number of times the process has started from the previous run.
3019 */
3020 int mLastStarts;
3021
3022 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003023 * The amount of foreground time loaded from the previous run
3024 */
3025 long mLastForegroundTime;
3026
3027 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003028 * The amount of user time when last unplugged.
3029 */
3030 long mUnpluggedUserTime;
3031
3032 /**
3033 * The amount of system time when last unplugged.
3034 */
3035 long mUnpluggedSystemTime;
3036
3037 /**
3038 * The number of times the process has started before unplugged.
3039 */
3040 int mUnpluggedStarts;
3041
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003042 /**
3043 * The amount of foreground time since unplugged.
3044 */
3045 long mUnpluggedForegroundTime;
3046
Amith Yamasanie43530a2009-08-21 13:11:37 -07003047 SamplingCounter[] mSpeedBins;
3048
Dianne Hackborn287952c2010-09-22 22:34:31 -07003049 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003051 Proc() {
3052 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003053 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003056 public void unplug(long batteryUptime, long batteryRealtime) {
3057 mUnpluggedUserTime = mUserTime;
3058 mUnpluggedSystemTime = mSystemTime;
3059 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003060 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 }
3062
3063 public void plug(long batteryUptime, long batteryRealtime) {
3064 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003065
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003066 void detach() {
3067 mUnpluggables.remove(this);
3068 for (int i = 0; i < mSpeedBins.length; i++) {
3069 SamplingCounter c = mSpeedBins[i];
3070 if (c != null) {
3071 mUnpluggables.remove(c);
3072 mSpeedBins[i] = null;
3073 }
3074 }
3075 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003076
Dianne Hackborn287952c2010-09-22 22:34:31 -07003077 public int countExcessivePowers() {
3078 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003079 }
3080
Dianne Hackborn287952c2010-09-22 22:34:31 -07003081 public ExcessivePower getExcessivePower(int i) {
3082 if (mExcessivePower != null) {
3083 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003084 }
3085 return null;
3086 }
3087
3088 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003089 if (mExcessivePower == null) {
3090 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003091 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07003092 ExcessivePower ew = new ExcessivePower();
3093 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003094 ew.overTime = overTime;
3095 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07003096 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003097 }
3098
Dianne Hackborn287952c2010-09-22 22:34:31 -07003099 public void addExcessiveCpu(long overTime, long usedTime) {
3100 if (mExcessivePower == null) {
3101 mExcessivePower = new ArrayList<ExcessivePower>();
3102 }
3103 ExcessivePower ew = new ExcessivePower();
3104 ew.type = ExcessivePower.TYPE_CPU;
3105 ew.overTime = overTime;
3106 ew.usedTime = usedTime;
3107 mExcessivePower.add(ew);
3108 }
3109
3110 void writeExcessivePowerToParcelLocked(Parcel out) {
3111 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003112 out.writeInt(0);
3113 return;
3114 }
3115
Dianne Hackborn287952c2010-09-22 22:34:31 -07003116 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003117 out.writeInt(N);
3118 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003119 ExcessivePower ew = mExcessivePower.get(i);
3120 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003121 out.writeLong(ew.overTime);
3122 out.writeLong(ew.usedTime);
3123 }
3124 }
3125
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003126 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003127 final int N = in.readInt();
3128 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003129 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003130 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003131 }
3132
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003133 if (N > 10000) {
3134 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
3135 return false;
3136 }
3137
Dianne Hackborn287952c2010-09-22 22:34:31 -07003138 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003139 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003140 ExcessivePower ew = new ExcessivePower();
3141 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003142 ew.overTime = in.readLong();
3143 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07003144 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003145 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003146 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003147 }
3148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003149 void writeToParcelLocked(Parcel out) {
3150 out.writeLong(mUserTime);
3151 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003152 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003153 out.writeInt(mStarts);
3154 out.writeLong(mLoadedUserTime);
3155 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003156 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003158 out.writeLong(mUnpluggedUserTime);
3159 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003160 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003161 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003162
3163 out.writeInt(mSpeedBins.length);
3164 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003165 SamplingCounter c = mSpeedBins[i];
3166 if (c != null) {
3167 out.writeInt(1);
3168 c.writeToParcel(out);
3169 } else {
3170 out.writeInt(0);
3171 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003172 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003173
Dianne Hackborn287952c2010-09-22 22:34:31 -07003174 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003175 }
3176
3177 void readFromParcelLocked(Parcel in) {
3178 mUserTime = in.readLong();
3179 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003180 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003181 mStarts = in.readInt();
3182 mLoadedUserTime = in.readLong();
3183 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003184 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003185 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003186 mLastUserTime = 0;
3187 mLastSystemTime = 0;
3188 mLastForegroundTime = 0;
3189 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 mUnpluggedUserTime = in.readLong();
3191 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003192 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003193 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07003194
3195 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003196 int steps = getCpuSpeedSteps();
3197 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07003198 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003199 if (in.readInt() != 0) {
3200 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
3201 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003202 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003203
Dianne Hackborn287952c2010-09-22 22:34:31 -07003204 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003205 }
3206
3207 public BatteryStatsImpl getBatteryStats() {
3208 return BatteryStatsImpl.this;
3209 }
3210
3211 public void addCpuTimeLocked(int utime, int stime) {
3212 mUserTime += utime;
3213 mSystemTime += stime;
3214 }
3215
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003216 public void addForegroundTimeLocked(long ttime) {
3217 mForegroundTime += ttime;
3218 }
3219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003220 public void incStartsLocked() {
3221 mStarts++;
3222 }
3223
3224 @Override
3225 public long getUserTime(int which) {
3226 long val;
3227 if (which == STATS_LAST) {
3228 val = mLastUserTime;
3229 } else {
3230 val = mUserTime;
3231 if (which == STATS_CURRENT) {
3232 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003233 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003234 val -= mUnpluggedUserTime;
3235 }
3236 }
3237 return val;
3238 }
3239
3240 @Override
3241 public long getSystemTime(int which) {
3242 long val;
3243 if (which == STATS_LAST) {
3244 val = mLastSystemTime;
3245 } else {
3246 val = mSystemTime;
3247 if (which == STATS_CURRENT) {
3248 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003249 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003250 val -= mUnpluggedSystemTime;
3251 }
3252 }
3253 return val;
3254 }
3255
3256 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003257 public long getForegroundTime(int which) {
3258 long val;
3259 if (which == STATS_LAST) {
3260 val = mLastForegroundTime;
3261 } else {
3262 val = mForegroundTime;
3263 if (which == STATS_CURRENT) {
3264 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003265 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003266 val -= mUnpluggedForegroundTime;
3267 }
3268 }
3269 return val;
3270 }
3271
3272 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003273 public int getStarts(int which) {
3274 int val;
3275 if (which == STATS_LAST) {
3276 val = mLastStarts;
3277 } else {
3278 val = mStarts;
3279 if (which == STATS_CURRENT) {
3280 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003281 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003282 val -= mUnpluggedStarts;
3283 }
3284 }
3285 return val;
3286 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003287
3288 /* Called by ActivityManagerService when CPU times are updated. */
3289 public void addSpeedStepTimes(long[] values) {
3290 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003291 long amt = values[i];
3292 if (amt != 0) {
3293 SamplingCounter c = mSpeedBins[i];
3294 if (c == null) {
3295 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
3296 }
3297 c.addCountAtomic(values[i]);
3298 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003299 }
3300 }
3301
3302 @Override
3303 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
3304 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003305 SamplingCounter c = mSpeedBins[speedStep];
3306 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07003307 } else {
3308 return 0;
3309 }
3310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 }
3312
3313 /**
3314 * The statistics associated with a particular package.
3315 */
3316 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
3317 /**
3318 * Number of times this package has done something that could wake up the
3319 * device from sleep.
3320 */
3321 int mWakeups;
3322
3323 /**
3324 * Number of things that could wake up the device loaded from a
3325 * previous save.
3326 */
3327 int mLoadedWakeups;
3328
3329 /**
3330 * Number of things that could wake up the device as of the
3331 * last run.
3332 */
3333 int mLastWakeups;
3334
3335 /**
3336 * Number of things that could wake up the device as of the
3337 * last run.
3338 */
3339 int mUnpluggedWakeups;
3340
3341 /**
3342 * The statics we have collected for this package's services.
3343 */
3344 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
3345
3346 Pkg() {
3347 mUnpluggables.add(this);
3348 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003350 public void unplug(long batteryUptime, long batteryRealtime) {
3351 mUnpluggedWakeups = mWakeups;
3352 }
3353
3354 public void plug(long batteryUptime, long batteryRealtime) {
3355 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003356
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003357 void detach() {
3358 mUnpluggables.remove(this);
3359 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003361 void readFromParcelLocked(Parcel in) {
3362 mWakeups = in.readInt();
3363 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003364 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365 mUnpluggedWakeups = in.readInt();
3366
3367 int numServs = in.readInt();
3368 mServiceStats.clear();
3369 for (int m = 0; m < numServs; m++) {
3370 String serviceName = in.readString();
3371 Uid.Pkg.Serv serv = new Serv();
3372 mServiceStats.put(serviceName, serv);
3373
3374 serv.readFromParcelLocked(in);
3375 }
3376 }
3377
3378 void writeToParcelLocked(Parcel out) {
3379 out.writeInt(mWakeups);
3380 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 out.writeInt(mUnpluggedWakeups);
3382
3383 out.writeInt(mServiceStats.size());
3384 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
3385 out.writeString(servEntry.getKey());
3386 Uid.Pkg.Serv serv = servEntry.getValue();
3387
3388 serv.writeToParcelLocked(out);
3389 }
3390 }
3391
3392 @Override
3393 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
3394 return mServiceStats;
3395 }
3396
3397 @Override
3398 public int getWakeups(int which) {
3399 int val;
3400 if (which == STATS_LAST) {
3401 val = mLastWakeups;
3402 } else {
3403 val = mWakeups;
3404 if (which == STATS_CURRENT) {
3405 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003406 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003407 val -= mUnpluggedWakeups;
3408 }
3409 }
3410
3411 return val;
3412 }
3413
3414 /**
3415 * The statistics associated with a particular service.
3416 */
3417 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
3418 /**
3419 * Total time (ms in battery uptime) the service has been left started.
3420 */
3421 long mStartTime;
3422
3423 /**
3424 * If service has been started and not yet stopped, this is
3425 * when it was started.
3426 */
3427 long mRunningSince;
3428
3429 /**
3430 * True if we are currently running.
3431 */
3432 boolean mRunning;
3433
3434 /**
3435 * Total number of times startService() has been called.
3436 */
3437 int mStarts;
3438
3439 /**
3440 * Total time (ms in battery uptime) the service has been left launched.
3441 */
3442 long mLaunchedTime;
3443
3444 /**
3445 * If service has been launched and not yet exited, this is
3446 * when it was launched (ms in battery uptime).
3447 */
3448 long mLaunchedSince;
3449
3450 /**
3451 * True if we are currently launched.
3452 */
3453 boolean mLaunched;
3454
3455 /**
3456 * Total number times the service has been launched.
3457 */
3458 int mLaunches;
3459
3460 /**
3461 * The amount of time spent started loaded from a previous save
3462 * (ms in battery uptime).
3463 */
3464 long mLoadedStartTime;
3465
3466 /**
3467 * The number of starts loaded from a previous save.
3468 */
3469 int mLoadedStarts;
3470
3471 /**
3472 * The number of launches loaded from a previous save.
3473 */
3474 int mLoadedLaunches;
3475
3476 /**
3477 * The amount of time spent started as of the last run (ms
3478 * in battery uptime).
3479 */
3480 long mLastStartTime;
3481
3482 /**
3483 * The number of starts as of the last run.
3484 */
3485 int mLastStarts;
3486
3487 /**
3488 * The number of launches as of the last run.
3489 */
3490 int mLastLaunches;
3491
3492 /**
3493 * The amount of time spent started when last unplugged (ms
3494 * in battery uptime).
3495 */
3496 long mUnpluggedStartTime;
3497
3498 /**
3499 * The number of starts when last unplugged.
3500 */
3501 int mUnpluggedStarts;
3502
3503 /**
3504 * The number of launches when last unplugged.
3505 */
3506 int mUnpluggedLaunches;
3507
3508 Serv() {
3509 mUnpluggables.add(this);
3510 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003512 public void unplug(long batteryUptime, long batteryRealtime) {
3513 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
3514 mUnpluggedStarts = mStarts;
3515 mUnpluggedLaunches = mLaunches;
3516 }
3517
3518 public void plug(long batteryUptime, long batteryRealtime) {
3519 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003520
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003521 void detach() {
3522 mUnpluggables.remove(this);
3523 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003525 void readFromParcelLocked(Parcel in) {
3526 mStartTime = in.readLong();
3527 mRunningSince = in.readLong();
3528 mRunning = in.readInt() != 0;
3529 mStarts = in.readInt();
3530 mLaunchedTime = in.readLong();
3531 mLaunchedSince = in.readLong();
3532 mLaunched = in.readInt() != 0;
3533 mLaunches = in.readInt();
3534 mLoadedStartTime = in.readLong();
3535 mLoadedStarts = in.readInt();
3536 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003537 mLastStartTime = 0;
3538 mLastStarts = 0;
3539 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003540 mUnpluggedStartTime = in.readLong();
3541 mUnpluggedStarts = in.readInt();
3542 mUnpluggedLaunches = in.readInt();
3543 }
3544
3545 void writeToParcelLocked(Parcel out) {
3546 out.writeLong(mStartTime);
3547 out.writeLong(mRunningSince);
3548 out.writeInt(mRunning ? 1 : 0);
3549 out.writeInt(mStarts);
3550 out.writeLong(mLaunchedTime);
3551 out.writeLong(mLaunchedSince);
3552 out.writeInt(mLaunched ? 1 : 0);
3553 out.writeInt(mLaunches);
3554 out.writeLong(mLoadedStartTime);
3555 out.writeInt(mLoadedStarts);
3556 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 out.writeLong(mUnpluggedStartTime);
3558 out.writeInt(mUnpluggedStarts);
3559 out.writeInt(mUnpluggedLaunches);
3560 }
3561
3562 long getLaunchTimeToNowLocked(long batteryUptime) {
3563 if (!mLaunched) return mLaunchedTime;
3564 return mLaunchedTime + batteryUptime - mLaunchedSince;
3565 }
3566
3567 long getStartTimeToNowLocked(long batteryUptime) {
3568 if (!mRunning) return mStartTime;
3569 return mStartTime + batteryUptime - mRunningSince;
3570 }
3571
3572 public void startLaunchedLocked() {
3573 if (!mLaunched) {
3574 mLaunches++;
3575 mLaunchedSince = getBatteryUptimeLocked();
3576 mLaunched = true;
3577 }
3578 }
3579
3580 public void stopLaunchedLocked() {
3581 if (mLaunched) {
3582 long time = getBatteryUptimeLocked() - mLaunchedSince;
3583 if (time > 0) {
3584 mLaunchedTime += time;
3585 } else {
3586 mLaunches--;
3587 }
3588 mLaunched = false;
3589 }
3590 }
3591
3592 public void startRunningLocked() {
3593 if (!mRunning) {
3594 mStarts++;
3595 mRunningSince = getBatteryUptimeLocked();
3596 mRunning = true;
3597 }
3598 }
3599
3600 public void stopRunningLocked() {
3601 if (mRunning) {
3602 long time = getBatteryUptimeLocked() - mRunningSince;
3603 if (time > 0) {
3604 mStartTime += time;
3605 } else {
3606 mStarts--;
3607 }
3608 mRunning = false;
3609 }
3610 }
3611
3612 public BatteryStatsImpl getBatteryStats() {
3613 return BatteryStatsImpl.this;
3614 }
3615
3616 @Override
3617 public int getLaunches(int which) {
3618 int val;
3619
3620 if (which == STATS_LAST) {
3621 val = mLastLaunches;
3622 } else {
3623 val = mLaunches;
3624 if (which == STATS_CURRENT) {
3625 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003626 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003627 val -= mUnpluggedLaunches;
3628 }
3629 }
3630
3631 return val;
3632 }
3633
3634 @Override
3635 public long getStartTime(long now, int which) {
3636 long val;
3637 if (which == STATS_LAST) {
3638 val = mLastStartTime;
3639 } else {
3640 val = getStartTimeToNowLocked(now);
3641 if (which == STATS_CURRENT) {
3642 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003643 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 val -= mUnpluggedStartTime;
3645 }
3646 }
3647
3648 return val;
3649 }
3650
3651 @Override
3652 public int getStarts(int which) {
3653 int val;
3654 if (which == STATS_LAST) {
3655 val = mLastStarts;
3656 } else {
3657 val = mStarts;
3658 if (which == STATS_CURRENT) {
3659 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003660 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003661 val -= mUnpluggedStarts;
3662 }
3663 }
3664
3665 return val;
3666 }
3667 }
3668
3669 public BatteryStatsImpl getBatteryStats() {
3670 return BatteryStatsImpl.this;
3671 }
3672
3673 public void incWakeupsLocked() {
3674 mWakeups++;
3675 }
3676
3677 final Serv newServiceStatsLocked() {
3678 return new Serv();
3679 }
3680 }
3681
3682 /**
3683 * Retrieve the statistics object for a particular process, creating
3684 * if needed.
3685 */
3686 public Proc getProcessStatsLocked(String name) {
3687 Proc ps = mProcessStats.get(name);
3688 if (ps == null) {
3689 ps = new Proc();
3690 mProcessStats.put(name, ps);
3691 }
3692
3693 return ps;
3694 }
3695
Dianne Hackbornb5e31652010-09-07 12:13:55 -07003696 public SparseArray<? extends Pid> getPidStats() {
3697 return mPids;
3698 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003699
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003700 public Pid getPidStatsLocked(int pid) {
3701 Pid p = mPids.get(pid);
3702 if (p == null) {
3703 p = new Pid();
3704 mPids.put(pid, p);
3705 }
3706 return p;
3707 }
3708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 /**
3710 * Retrieve the statistics object for a particular service, creating
3711 * if needed.
3712 */
3713 public Pkg getPackageStatsLocked(String name) {
3714 Pkg ps = mPackageStats.get(name);
3715 if (ps == null) {
3716 ps = new Pkg();
3717 mPackageStats.put(name, ps);
3718 }
3719
3720 return ps;
3721 }
3722
3723 /**
3724 * Retrieve the statistics object for a particular service, creating
3725 * if needed.
3726 */
3727 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
3728 Pkg ps = getPackageStatsLocked(pkg);
3729 Pkg.Serv ss = ps.mServiceStats.get(serv);
3730 if (ss == null) {
3731 ss = ps.newServiceStatsLocked();
3732 ps.mServiceStats.put(serv, ss);
3733 }
3734
3735 return ss;
3736 }
3737
Evan Millarc64edde2009-04-18 12:26:32 -07003738 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003739 Wakelock wl = mWakelockStats.get(name);
3740 if (wl == null) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08003741 if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) {
3742 name = BATCHED_WAKELOCK_NAME;
3743 wl = mWakelockStats.get(name);
3744 }
3745 if (wl == null) {
3746 wl = new Wakelock();
3747 mWakelockStats.put(name, wl);
3748 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 }
Evan Millarc64edde2009-04-18 12:26:32 -07003750 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003751 switch (type) {
3752 case WAKE_TYPE_PARTIAL:
3753 t = wl.mTimerPartial;
3754 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003755 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
3756 mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003757 wl.mTimerPartial = t;
3758 }
3759 return t;
3760 case WAKE_TYPE_FULL:
3761 t = wl.mTimerFull;
3762 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003763 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
3764 mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003765 wl.mTimerFull = t;
3766 }
3767 return t;
3768 case WAKE_TYPE_WINDOW:
3769 t = wl.mTimerWindow;
3770 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003771 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
3772 mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 wl.mTimerWindow = t;
3774 }
3775 return t;
3776 default:
3777 throw new IllegalArgumentException("type=" + type);
3778 }
3779 }
3780
Evan Millarc64edde2009-04-18 12:26:32 -07003781 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003782 Sensor se = mSensorStats.get(sensor);
3783 if (se == null) {
3784 if (!create) {
3785 return null;
3786 }
3787 se = new Sensor(sensor);
3788 mSensorStats.put(sensor, se);
3789 }
Evan Millarc64edde2009-04-18 12:26:32 -07003790 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791 if (t != null) {
3792 return t;
3793 }
Evan Millarc64edde2009-04-18 12:26:32 -07003794 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003796 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 mSensorTimers.put(sensor, timers);
3798 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003799 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003800 se.mTimer = t;
3801 return t;
3802 }
3803
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003804 public void noteStartWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003805 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003806 if (t != null) {
3807 t.startRunningLocked(BatteryStatsImpl.this);
3808 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003809 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003810 Pid p = getPidStatsLocked(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003811 if (p.mWakeStart == 0) {
3812 p.mWakeStart = SystemClock.elapsedRealtime();
3813 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003815 }
3816
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003817 public void noteStopWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003818 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003819 if (t != null) {
3820 t.stopRunningLocked(BatteryStatsImpl.this);
3821 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003822 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003823 Pid p = mPids.get(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003824 if (p != null && p.mWakeStart != 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003825 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
3826 p.mWakeStart = 0;
3827 }
3828 }
3829 }
3830
3831 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
3832 Proc p = getProcessStatsLocked(proc);
3833 if (p != null) {
3834 p.addExcessiveWake(overTime, usedTime);
3835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003837
Dianne Hackborn287952c2010-09-22 22:34:31 -07003838 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
3839 Proc p = getProcessStatsLocked(proc);
3840 if (p != null) {
3841 p.addExcessiveCpu(overTime, usedTime);
3842 }
3843 }
3844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003845 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07003846 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003847 if (t != null) {
3848 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003850 }
3851
3852 public void noteStopSensor(int sensor) {
3853 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07003854 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003855 if (t != null) {
3856 t.stopRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003858 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003860 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07003861 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003862 if (t != null) {
3863 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003864 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003865 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003867 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07003868 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003869 if (t != null) {
3870 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003872 }
3873
3874 public BatteryStatsImpl getBatteryStats() {
3875 return BatteryStatsImpl.this;
3876 }
3877 }
3878
3879 public BatteryStatsImpl(String filename) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003880 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003881 mHandler = new MyHandler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003882 mStartCount++;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003883 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003884 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003885 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003886 }
3887 mInputEventCounter = new Counter(mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003888 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
Wink Saville52840902011-02-18 12:40:47 -08003889 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003890 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003891 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003892 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003893 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003894 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003895 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003896 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003897 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003898 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
3899 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
3900 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003901 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003902 initTimes();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003903 mTrackBatteryPastUptime = 0;
3904 mTrackBatteryPastRealtime = 0;
3905 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
3906 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
3907 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
3908 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07003909 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003910 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07003911 mDischargeCurrentLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08003912 initDischarge();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 }
3914
3915 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003916 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003917 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 readFromParcel(p);
3919 }
3920
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003921 public void setCallback(BatteryCallback cb) {
3922 mCallback = cb;
3923 }
3924
Amith Yamasanie43530a2009-08-21 13:11:37 -07003925 public void setNumSpeedSteps(int steps) {
3926 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
3927 }
3928
Amith Yamasanif37447b2009-10-08 18:28:01 -07003929 public void setRadioScanningTimeout(long timeout) {
3930 if (mPhoneSignalScanningTimer != null) {
3931 mPhoneSignalScanningTimer.setTimeout(timeout);
3932 }
3933 }
3934
Dianne Hackbornce2ef762010-09-20 11:39:14 -07003935 private HistoryItem mHistoryIterator;
3936
3937 public boolean startIteratingHistoryLocked() {
3938 return (mHistoryIterator = mHistory) != null;
3939 }
3940
3941 public boolean getNextHistoryLocked(HistoryItem out) {
3942 HistoryItem cur = mHistoryIterator;
3943 if (cur == null) {
3944 return false;
3945 }
3946 out.setTo(cur);
3947 mHistoryIterator = cur.next;
3948 return true;
3949 }
3950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003952 public HistoryItem getHistory() {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003953 return mHistory;
3954 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003955
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003956 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07003957 public long getHistoryBaseTime() {
3958 return mHistoryBaseTime;
3959 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003960
Dianne Hackbornb5e31652010-09-07 12:13:55 -07003961 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003962 public int getStartCount() {
3963 return mStartCount;
3964 }
3965
3966 public boolean isOnBattery() {
3967 return mOnBattery;
3968 }
3969
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003970 public boolean isScreenOn() {
3971 return mScreenOn;
3972 }
3973
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003974 void initTimes() {
3975 mBatteryRealtime = mTrackBatteryPastUptime = 0;
3976 mBatteryUptime = mTrackBatteryPastRealtime = 0;
3977 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
3978 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
3979 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
3980 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
3981 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003982
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08003983 void initDischarge() {
3984 mLowDischargeAmountSinceCharge = 0;
3985 mHighDischargeAmountSinceCharge = 0;
3986 mDischargeAmountScreenOn = 0;
3987 mDischargeAmountScreenOnSinceCharge = 0;
3988 mDischargeAmountScreenOff = 0;
3989 mDischargeAmountScreenOffSinceCharge = 0;
3990 }
3991
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003992 public void resetAllStatsLocked() {
3993 mStartCount = 0;
3994 initTimes();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003995 mScreenOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003996 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003997 mScreenBrightnessTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003998 }
3999 mInputEventCounter.reset(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004000 mPhoneOnTimer.reset(this, false);
4001 mAudioOnTimer.reset(this, false);
4002 mVideoOnTimer.reset(this, false);
Wink Saville52840902011-02-18 12:40:47 -08004003 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004004 mPhoneSignalStrengthsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004005 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004006 mPhoneSignalScanningTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004007 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004008 mPhoneDataConnectionsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004009 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004010 mWifiOnTimer.reset(this, false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004011 mGlobalWifiRunningTimer.reset(this, false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004012 mBluetoothOnTimer.reset(this, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004013
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004014 for (int i=0; i<mUidStats.size(); i++) {
4015 if (mUidStats.valueAt(i).reset()) {
4016 mUidStats.remove(mUidStats.keyAt(i));
4017 i--;
4018 }
4019 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004020
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004021 if (mKernelWakelockStats.size() > 0) {
4022 for (SamplingTimer timer : mKernelWakelockStats.values()) {
4023 mUnpluggables.remove(timer);
4024 }
4025 mKernelWakelockStats.clear();
4026 }
4027
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004028 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004029
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004030 clearHistoryLocked();
4031 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004032
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004033 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004034 if (oldScreenOn) {
4035 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
4036 if (diff > 0) {
4037 mDischargeAmountScreenOn += diff;
4038 mDischargeAmountScreenOnSinceCharge += diff;
4039 }
4040 } else {
4041 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
4042 if (diff > 0) {
4043 mDischargeAmountScreenOff += diff;
4044 mDischargeAmountScreenOffSinceCharge += diff;
4045 }
4046 }
4047 if (newScreenOn) {
4048 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
4049 mDischargeScreenOffUnplugLevel = 0;
4050 } else {
4051 mDischargeScreenOnUnplugLevel = 0;
4052 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
4053 }
4054 }
4055
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004056 void setOnBattery(boolean onBattery, int oldStatus, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004057 synchronized(this) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004058 setOnBatteryLocked(onBattery, oldStatus, level);
4059 }
4060 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004061
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004062 void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
4063 boolean doWrite = false;
4064 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
4065 m.arg1 = onBattery ? 1 : 0;
4066 mHandler.sendMessage(m);
4067 mOnBattery = mOnBatteryInternal = onBattery;
4068
4069 long uptime = SystemClock.uptimeMillis() * 1000;
4070 long mSecRealtime = SystemClock.elapsedRealtime();
4071 long realtime = mSecRealtime * 1000;
4072 if (onBattery) {
4073 // We will reset our status if we are unplugging after the
4074 // battery was last full, or the level is at 100, or
4075 // we have gone through a significant charge (from a very low
4076 // level to a now very high level).
4077 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
4078 || level >= 90
4079 || (mDischargeCurrentLevel < 20 && level >= 80)) {
4080 doWrite = true;
4081 resetAllStatsLocked();
4082 mDischargeStartLevel = level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004083 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004084 updateKernelWakelocksLocked();
4085 mHistoryCur.batteryLevel = (byte)level;
4086 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4087 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
4088 + Integer.toHexString(mHistoryCur.states));
4089 addHistoryRecordLocked(mSecRealtime);
4090 mTrackBatteryUptimeStart = uptime;
4091 mTrackBatteryRealtimeStart = realtime;
4092 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
4093 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
4094 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
4095 if (mScreenOn) {
4096 mDischargeScreenOnUnplugLevel = level;
4097 mDischargeScreenOffUnplugLevel = 0;
4098 } else {
4099 mDischargeScreenOnUnplugLevel = 0;
4100 mDischargeScreenOffUnplugLevel = level;
4101 }
4102 mDischargeAmountScreenOn = 0;
4103 mDischargeAmountScreenOff = 0;
4104 doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
4105 } else {
4106 updateKernelWakelocksLocked();
4107 mHistoryCur.batteryLevel = (byte)level;
4108 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4109 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
4110 + Integer.toHexString(mHistoryCur.states));
4111 addHistoryRecordLocked(mSecRealtime);
4112 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
4113 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
4114 mDischargeCurrentLevel = level;
4115 if (level < mDischargeUnplugLevel) {
4116 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
4117 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
4118 }
4119 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
4120 doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
4121 }
4122 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
4123 if (mFile != null) {
4124 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004125 }
4126 }
4127 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004128
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004129 // This should probably be exposed in the API, though it's not critical
4130 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004131
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004132 public void setBatteryState(int status, int health, int plugType, int level,
4133 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004134 synchronized(this) {
4135 boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
4136 int oldStatus = mHistoryCur.batteryStatus;
4137 if (!mHaveBatteryLevel) {
4138 mHaveBatteryLevel = true;
4139 // We start out assuming that the device is plugged in (not
4140 // on battery). If our first report is now that we are indeed
4141 // plugged in, then twiddle our state to correctly reflect that
4142 // since we won't be going through the full setOnBattery().
4143 if (onBattery == mOnBattery) {
4144 if (onBattery) {
4145 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4146 } else {
4147 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4148 }
4149 }
4150 oldStatus = status;
4151 }
4152 if (onBattery) {
4153 mDischargeCurrentLevel = level;
4154 mRecordingHistory = true;
4155 }
4156 if (onBattery != mOnBattery) {
4157 mHistoryCur.batteryLevel = (byte)level;
4158 mHistoryCur.batteryStatus = (byte)status;
4159 mHistoryCur.batteryHealth = (byte)health;
4160 mHistoryCur.batteryPlugType = (byte)plugType;
4161 mHistoryCur.batteryTemperature = (char)temp;
4162 mHistoryCur.batteryVoltage = (char)volt;
4163 setOnBatteryLocked(onBattery, oldStatus, level);
4164 } else {
4165 boolean changed = false;
4166 if (mHistoryCur.batteryLevel != level) {
4167 mHistoryCur.batteryLevel = (byte)level;
4168 changed = true;
4169 }
4170 if (mHistoryCur.batteryStatus != status) {
4171 mHistoryCur.batteryStatus = (byte)status;
4172 changed = true;
4173 }
4174 if (mHistoryCur.batteryHealth != health) {
4175 mHistoryCur.batteryHealth = (byte)health;
4176 changed = true;
4177 }
4178 if (mHistoryCur.batteryPlugType != plugType) {
4179 mHistoryCur.batteryPlugType = (byte)plugType;
4180 changed = true;
4181 }
4182 if (temp >= (mHistoryCur.batteryTemperature+10)
4183 || temp <= (mHistoryCur.batteryTemperature-10)) {
4184 mHistoryCur.batteryTemperature = (char)temp;
4185 changed = true;
4186 }
4187 if (volt > (mHistoryCur.batteryVoltage+20)
4188 || volt < (mHistoryCur.batteryVoltage-20)) {
4189 mHistoryCur.batteryVoltage = (char)volt;
4190 changed = true;
4191 }
4192 if (changed) {
4193 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004194 }
4195 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004196 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
4197 // We don't record history while we are plugged in and fully charged.
4198 // The next time we are unplugged, history will be cleared.
4199 mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004200 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004201 }
Evan Millar633a1742009-04-02 16:36:33 -07004202 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004203
Evan Millarc64edde2009-04-18 12:26:32 -07004204 public void updateKernelWakelocksLocked() {
4205 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004206
Marco Nelissend8593312009-04-30 14:45:06 -07004207 if (m == null) {
4208 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004209 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07004210 return;
4211 }
4212
Evan Millarc64edde2009-04-18 12:26:32 -07004213 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
4214 String name = ent.getKey();
4215 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004216
Evan Millarc64edde2009-04-18 12:26:32 -07004217 SamplingTimer kwlt = mKernelWakelockStats.get(name);
4218 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004219 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07004220 true /* track reported values */);
4221 mKernelWakelockStats.put(name, kwlt);
4222 }
4223 kwlt.updateCurrentReportedCount(kws.mCount);
4224 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
4225 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
4226 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004227
Evan Millarc64edde2009-04-18 12:26:32 -07004228 if (m.size() != mKernelWakelockStats.size()) {
4229 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
4230 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4231 SamplingTimer st = ent.getValue();
4232 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
4233 st.setStale();
4234 }
4235 }
4236 }
4237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238
4239 public long getAwakeTimeBattery() {
4240 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
4241 }
4242
4243 public long getAwakeTimePlugged() {
4244 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
4245 }
4246
4247 @Override
4248 public long computeUptime(long curTime, int which) {
4249 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004250 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004251 case STATS_LAST: return mLastUptime;
4252 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004253 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 }
4255 return 0;
4256 }
4257
4258 @Override
4259 public long computeRealtime(long curTime, int which) {
4260 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004261 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004262 case STATS_LAST: return mLastRealtime;
4263 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004264 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004265 }
4266 return 0;
4267 }
4268
4269 @Override
4270 public long computeBatteryUptime(long curTime, int which) {
4271 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004272 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004273 return mBatteryUptime + getBatteryUptime(curTime);
4274 case STATS_LAST:
4275 return mBatteryLastUptime;
4276 case STATS_CURRENT:
4277 return getBatteryUptime(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004278 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
4280 }
4281 return 0;
4282 }
4283
4284 @Override
4285 public long computeBatteryRealtime(long curTime, int which) {
4286 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004287 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004288 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
4289 case STATS_LAST:
4290 return mBatteryLastRealtime;
4291 case STATS_CURRENT:
4292 return getBatteryRealtimeLocked(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004293 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004294 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
4295 }
4296 return 0;
4297 }
4298
4299 long getBatteryUptimeLocked(long curTime) {
4300 long time = mTrackBatteryPastUptime;
4301 if (mOnBatteryInternal) {
4302 time += curTime - mTrackBatteryUptimeStart;
4303 }
4304 return time;
4305 }
4306
4307 long getBatteryUptimeLocked() {
4308 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
4309 }
4310
4311 @Override
4312 public long getBatteryUptime(long curTime) {
4313 return getBatteryUptimeLocked(curTime);
4314 }
4315
4316 long getBatteryRealtimeLocked(long curTime) {
4317 long time = mTrackBatteryPastRealtime;
4318 if (mOnBatteryInternal) {
4319 time += curTime - mTrackBatteryRealtimeStart;
4320 }
4321 return time;
4322 }
4323
4324 @Override
4325 public long getBatteryRealtime(long curTime) {
4326 return getBatteryRealtimeLocked(curTime);
4327 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004328
4329 private long getTcpBytes(long current, long[] dataBytes, int which) {
4330 if (which == STATS_LAST) {
4331 return dataBytes[STATS_LAST];
4332 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004333 if (which == STATS_SINCE_UNPLUGGED) {
4334 if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004335 return dataBytes[STATS_LAST];
4336 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004337 return current - dataBytes[STATS_SINCE_UNPLUGGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004338 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004339 } else if (which == STATS_SINCE_CHARGED) {
4340 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004341 }
4342 return current - dataBytes[STATS_CURRENT];
4343 }
4344 }
4345
4346 /** Only STATS_UNPLUGGED works properly */
4347 public long getMobileTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004348 return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004349 }
4350
4351 /** Only STATS_UNPLUGGED works properly */
4352 public long getMobileTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004353 return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004354 }
4355
4356 /** Only STATS_UNPLUGGED works properly */
4357 public long getTotalTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004358 return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004359 }
4360
4361 /** Only STATS_UNPLUGGED works properly */
4362 public long getTotalTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004363 return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004364 }
4365
The Android Open Source Project10592532009-03-18 17:39:46 -07004366 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004367 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004368 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004369 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004370 }
4371 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004372
Evan Millar633a1742009-04-02 16:36:33 -07004373 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004374 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004375 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004376
The Android Open Source Project10592532009-03-18 17:39:46 -07004377 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004378 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004379 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004380 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004381 }
4382 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004383
Evan Millar633a1742009-04-02 16:36:33 -07004384 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004385 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004387
Amith Yamasanie43530a2009-08-21 13:11:37 -07004388 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004389 public int getLowDischargeAmountSinceCharge() {
4390 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004391 int val = mLowDischargeAmountSinceCharge;
4392 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4393 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
4394 }
4395 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004396 }
4397 }
4398
4399 @Override
4400 public int getHighDischargeAmountSinceCharge() {
4401 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004402 int val = mHighDischargeAmountSinceCharge;
4403 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4404 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
4405 }
4406 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004407 }
4408 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004409
4410 public int getDischargeAmountScreenOn() {
4411 synchronized(this) {
4412 int val = mDischargeAmountScreenOn;
4413 if (mOnBattery && mScreenOn
4414 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4415 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4416 }
4417 return val;
4418 }
4419 }
4420
4421 public int getDischargeAmountScreenOnSinceCharge() {
4422 synchronized(this) {
4423 int val = mDischargeAmountScreenOnSinceCharge;
4424 if (mOnBattery && mScreenOn
4425 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4426 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4427 }
4428 return val;
4429 }
4430 }
4431
4432 public int getDischargeAmountScreenOff() {
4433 synchronized(this) {
4434 int val = mDischargeAmountScreenOff;
4435 if (mOnBattery && !mScreenOn
4436 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4437 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4438 }
4439 return val;
4440 }
4441 }
4442
4443 public int getDischargeAmountScreenOffSinceCharge() {
4444 synchronized(this) {
4445 int val = mDischargeAmountScreenOffSinceCharge;
4446 if (mOnBattery && !mScreenOn
4447 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4448 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4449 }
4450 return val;
4451 }
4452 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004453
4454 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07004455 public int getCpuSpeedSteps() {
4456 return sNumSpeedSteps;
4457 }
4458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004459 /**
4460 * Retrieve the statistics object for a particular uid, creating if needed.
4461 */
4462 public Uid getUidStatsLocked(int uid) {
4463 Uid u = mUidStats.get(uid);
4464 if (u == null) {
4465 u = new Uid(uid);
4466 mUidStats.put(uid, u);
4467 }
4468 return u;
4469 }
4470
4471 /**
4472 * Remove the statistics object for a particular uid.
4473 */
4474 public void removeUidStatsLocked(int uid) {
4475 mUidStats.remove(uid);
4476 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 /**
4479 * Retrieve the statistics object for a particular process, creating
4480 * if needed.
4481 */
4482 public Uid.Proc getProcessStatsLocked(int uid, String name) {
4483 Uid u = getUidStatsLocked(uid);
4484 return u.getProcessStatsLocked(name);
4485 }
4486
4487 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004488 * Retrieve the statistics object for a particular process, given
4489 * the name of the process.
4490 * @param name process name
4491 * @return the statistics object for the process
4492 */
Amith Yamasani819f9282009-06-24 23:18:15 -07004493 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004494 int uid;
4495 if (mUidCache.containsKey(name)) {
4496 uid = mUidCache.get(name);
4497 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07004498 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004499 mUidCache.put(name, uid);
4500 }
4501 Uid u = getUidStatsLocked(uid);
4502 return u.getProcessStatsLocked(name);
4503 }
4504
4505 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004506 * Retrieve the statistics object for a particular process, creating
4507 * if needed.
4508 */
4509 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
4510 Uid u = getUidStatsLocked(uid);
4511 return u.getPackageStatsLocked(pkg);
4512 }
4513
4514 /**
4515 * Retrieve the statistics object for a particular service, creating
4516 * if needed.
4517 */
4518 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
4519 Uid u = getUidStatsLocked(uid);
4520 return u.getServiceStatsLocked(pkg, name);
4521 }
4522
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004523 /**
4524 * Massage data to distribute any reasonable work down to more specific
4525 * owners. Must only be called on a dead BatteryStats object!
4526 */
4527 public void distributeWorkLocked(int which) {
4528 // Aggregate all CPU time associated with WIFI.
4529 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
4530 if (wifiUid != null) {
4531 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
4532 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
4533 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
4534 for (int i=0; i<mUidStats.size(); i++) {
4535 Uid uid = mUidStats.valueAt(i);
4536 if (uid.mUid != Process.WIFI_UID) {
4537 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
4538 if (uidRunningTime > 0) {
4539 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
4540 long time = proc.getUserTime(which);
4541 time = (time*uidRunningTime)/totalRunningTime;
4542 uidProc.mUserTime += time;
4543 proc.mUserTime -= time;
4544 time = proc.getSystemTime(which);
4545 time = (time*uidRunningTime)/totalRunningTime;
4546 uidProc.mSystemTime += time;
4547 proc.mSystemTime -= time;
4548 time = proc.getForegroundTime(which);
4549 time = (time*uidRunningTime)/totalRunningTime;
4550 uidProc.mForegroundTime += time;
4551 proc.mForegroundTime -= time;
4552 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
4553 SamplingCounter sc = proc.mSpeedBins[sb];
4554 if (sc != null) {
4555 time = sc.getCountLocked(which);
4556 time = (time*uidRunningTime)/totalRunningTime;
4557 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
4558 if (uidSc == null) {
4559 uidSc = new SamplingCounter(mUnpluggables);
4560 uidProc.mSpeedBins[sb] = uidSc;
4561 }
4562 uidSc.mCount.addAndGet((int)time);
4563 sc.mCount.addAndGet((int)-time);
4564 }
4565 }
4566 totalRunningTime -= uidRunningTime;
4567 }
4568 }
4569 }
4570 }
4571 }
4572 }
4573
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004574 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004575 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004576 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004577 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004578
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004579 Parcel mPendingWrite = null;
4580 final ReentrantLock mWriteLock = new ReentrantLock();
4581
4582 public void writeAsyncLocked() {
4583 writeLocked(false);
4584 }
4585
4586 public void writeSyncLocked() {
4587 writeLocked(true);
4588 }
4589
4590 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004591 if (mFile == null) {
4592 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004593 return;
4594 }
4595
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004596 if (mShuttingDown) {
4597 return;
4598 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004599
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004600 Parcel out = Parcel.obtain();
4601 writeSummaryToParcel(out);
4602 mLastWriteTime = SystemClock.elapsedRealtime();
4603
4604 if (mPendingWrite != null) {
4605 mPendingWrite.recycle();
4606 }
4607 mPendingWrite = out;
4608
4609 if (sync) {
4610 commitPendingDataToDisk();
4611 } else {
4612 Thread thr = new Thread("BatteryStats-Write") {
4613 @Override
4614 public void run() {
4615 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
4616 commitPendingDataToDisk();
4617 }
4618 };
4619 thr.start();
4620 }
4621 }
4622
4623 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004624 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004625 synchronized (this) {
4626 next = mPendingWrite;
4627 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004628 if (next == null) {
4629 return;
4630 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004631
4632 mWriteLock.lock();
4633 }
4634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004635 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004636 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004637 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07004639 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004640 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004641 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004643 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004644 mFile.rollback();
4645 } finally {
4646 next.recycle();
4647 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07004648 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004649 }
4650
4651 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
4652 int pos = 0;
4653 int avail = stream.available();
4654 byte[] data = new byte[avail];
4655 while (true) {
4656 int amt = stream.read(data, pos, data.length-pos);
4657 //Log.i("foo", "Read " + amt + " bytes at " + pos
4658 // + " of avail " + data.length);
4659 if (amt <= 0) {
4660 //Log.i("foo", "**** FINISHED READING: pos=" + pos
4661 // + " len=" + data.length);
4662 return data;
4663 }
4664 pos += amt;
4665 avail = stream.available();
4666 if (avail > data.length-pos) {
4667 byte[] newData = new byte[pos+avail];
4668 System.arraycopy(data, 0, newData, 0, pos);
4669 data = newData;
4670 }
4671 }
4672 }
4673
4674 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004675 if (mFile == null) {
4676 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004677 return;
4678 }
4679
4680 mUidStats.clear();
4681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004682 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004683 File file = mFile.chooseForRead();
4684 if (!file.exists()) {
4685 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004687 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688
4689 byte[] raw = readFully(stream);
4690 Parcel in = Parcel.obtain();
4691 in.unmarshall(raw, 0, raw.length);
4692 in.setDataPosition(0);
4693 stream.close();
4694
4695 readSummaryFromParcel(in);
4696 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004697 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004698 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004699
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004700 addHistoryRecordLocked(SystemClock.elapsedRealtime(), HistoryItem.CMD_START);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004701 }
4702
4703 public int describeContents() {
4704 return 0;
4705 }
4706
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004707 void readHistory(Parcel in) {
4708 mHistory = mHistoryEnd = mHistoryCache = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004709 mHistoryBaseTime = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004710 long time;
Per Andersson3d865242011-02-21 09:55:42 +01004711 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004712 HistoryItem rec = new HistoryItem(time, in);
4713 addHistoryRecordLocked(rec);
4714 if (rec.time > mHistoryBaseTime) {
4715 mHistoryBaseTime = rec.time;
4716 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004717 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004718
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07004719 long oldnow = SystemClock.elapsedRealtime() - (5*60*100);
4720 if (oldnow > 0) {
4721 // If the system process has restarted, but not the entire
4722 // system, then the mHistoryBaseTime already accounts for
4723 // much of the elapsed time. We thus want to adjust it back,
4724 // to avoid large gaps in the data. We determine we are
4725 // in this case by arbitrarily saying it is so if at this
4726 // point in boot the elapsed time is already more than 5 seconds.
4727 mHistoryBaseTime -= oldnow;
4728 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004729 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004730
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004731 void writeHistory(Parcel out) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004732 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004733 while (rec != null) {
4734 if (rec.time >= 0) rec.writeToParcel(out, 0);
4735 rec = rec.next;
4736 }
4737 out.writeLong(-1);
4738 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 private void readSummaryFromParcel(Parcel in) {
4741 final int version = in.readInt();
4742 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004743 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 + ", expected " + VERSION + "; erasing old stats");
4745 return;
4746 }
4747
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004748 readHistory(in);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004750 mStartCount = in.readInt();
4751 mBatteryUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004752 mBatteryRealtime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004753 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 mRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004755 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07004756 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004757 mLowDischargeAmountSinceCharge = in.readInt();
4758 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004759 mDischargeAmountScreenOnSinceCharge = in.readInt();
4760 mDischargeAmountScreenOffSinceCharge = in.readInt();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764 mScreenOn = false;
4765 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004766 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4767 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
4768 }
4769 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 mPhoneOn = false;
4771 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08004772 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07004773 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
4774 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004775 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004776 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4777 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
4778 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004779 mWifiOn = false;
4780 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004781 mGlobalWifiRunning = false;
4782 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07004783 mBluetoothOn = false;
4784 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004785
Evan Millarc64edde2009-04-18 12:26:32 -07004786 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004787 if (NKW > 10000) {
4788 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
4789 return;
4790 }
Evan Millarc64edde2009-04-18 12:26:32 -07004791 for (int ikw = 0; ikw < NKW; ikw++) {
4792 if (in.readInt() != 0) {
4793 String kwltName = in.readString();
4794 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
4795 }
4796 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004797
4798 sNumSpeedSteps = in.readInt();
4799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004800 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004801 if (NU > 10000) {
4802 Slog.w(TAG, "File corrupt: too many uids " + NU);
4803 return;
4804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004805 for (int iu = 0; iu < NU; iu++) {
4806 int uid = in.readInt();
4807 Uid u = new Uid(uid);
4808 mUidStats.put(uid, u);
4809
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004810 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004811 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004812 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004813 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004814 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004815 if (in.readInt() != 0) {
4816 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
4817 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004818 u.mScanWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004819 if (in.readInt() != 0) {
4820 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
4821 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004822 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004823 if (in.readInt() != 0) {
4824 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
4825 }
4826 u.mAudioTurnedOn = false;
4827 if (in.readInt() != 0) {
4828 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
4829 }
4830 u.mVideoTurnedOn = false;
4831 if (in.readInt() != 0) {
4832 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
4833 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004834
Dianne Hackborn617f8772009-03-31 15:04:46 -07004835 if (in.readInt() != 0) {
4836 if (u.mUserActivityCounters == null) {
4837 u.initUserActivityLocked();
4838 }
4839 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
4840 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
4841 }
4842 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004845 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004846 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
4847 return;
4848 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004849 for (int iw = 0; iw < NW; iw++) {
4850 String wlName = in.readString();
4851 if (in.readInt() != 0) {
4852 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
4853 }
4854 if (in.readInt() != 0) {
4855 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
4856 }
4857 if (in.readInt() != 0) {
4858 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
4859 }
4860 }
4861
4862 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004863 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004864 Slog.w(TAG, "File corrupt: too many sensors " + NP);
4865 return;
4866 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 for (int is = 0; is < NP; is++) {
4868 int seNumber = in.readInt();
4869 if (in.readInt() != 0) {
4870 u.getSensorTimerLocked(seNumber, true)
4871 .readSummaryFromParcelLocked(in);
4872 }
4873 }
4874
4875 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004876 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004877 Slog.w(TAG, "File corrupt: too many processes " + NP);
4878 return;
4879 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004880 for (int ip = 0; ip < NP; ip++) {
4881 String procName = in.readString();
4882 Uid.Proc p = u.getProcessStatsLocked(procName);
4883 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004884 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004885 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004886 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004887 if (NSB > 100) {
4888 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
4889 return;
4890 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004891 p.mSpeedBins = new SamplingCounter[NSB];
4892 for (int i=0; i<NSB; i++) {
4893 if (in.readInt() != 0) {
4894 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables);
4895 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
4896 }
4897 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004898 if (!p.readExcessivePowerFromParcelLocked(in)) {
4899 return;
4900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004901 }
4902
4903 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004904 if (NP > 10000) {
4905 Slog.w(TAG, "File corrupt: too many packages " + NP);
4906 return;
4907 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004908 for (int ip = 0; ip < NP; ip++) {
4909 String pkgName = in.readString();
4910 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
4911 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004912 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08004913 if (NS > 1000) {
4914 Slog.w(TAG, "File corrupt: too many services " + NS);
4915 return;
4916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004917 for (int is = 0; is < NS; is++) {
4918 String servName = in.readString();
4919 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
4920 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004921 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004923 }
4924 }
4925
4926 u.mLoadedTcpBytesReceived = in.readLong();
4927 u.mLoadedTcpBytesSent = in.readLong();
4928 }
4929 }
4930
4931 /**
4932 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
4933 * disk. This format does not allow a lossless round-trip.
4934 *
4935 * @param out the Parcel to be written to.
4936 */
4937 public void writeSummaryToParcel(Parcel out) {
4938 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
4939 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
4940 final long NOW = getBatteryUptimeLocked(NOW_SYS);
4941 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
4942
4943 out.writeInt(VERSION);
4944
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004945 writeHistory(out);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004947 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004948 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004949 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004950 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004951 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004952 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07004953 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004954 out.writeInt(getLowDischargeAmountSinceCharge());
4955 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004956 out.writeInt(getDischargeAmountScreenOnSinceCharge());
4957 out.writeInt(getDischargeAmountScreenOffSinceCharge());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958
4959 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004960 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4961 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
4962 }
4963 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004964 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Wink Saville52840902011-02-18 12:40:47 -08004965 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07004966 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
4967 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004968 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004969 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4970 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
4971 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004972 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004973 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07004974 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004975
Evan Millarc64edde2009-04-18 12:26:32 -07004976 out.writeInt(mKernelWakelockStats.size());
4977 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4978 Timer kwlt = ent.getValue();
4979 if (kwlt != null) {
4980 out.writeInt(1);
4981 out.writeString(ent.getKey());
4982 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
4983 } else {
4984 out.writeInt(0);
4985 }
4986 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004987
Amith Yamasanie43530a2009-08-21 13:11:37 -07004988 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004989 final int NU = mUidStats.size();
4990 out.writeInt(NU);
4991 for (int iu = 0; iu < NU; iu++) {
4992 out.writeInt(mUidStats.keyAt(iu));
4993 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004994
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004995 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004996 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004997 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004998 } else {
4999 out.writeInt(0);
5000 }
5001 if (u.mFullWifiLockTimer != null) {
5002 out.writeInt(1);
5003 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5004 } else {
5005 out.writeInt(0);
5006 }
5007 if (u.mScanWifiLockTimer != null) {
5008 out.writeInt(1);
5009 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5010 } else {
5011 out.writeInt(0);
5012 }
5013 if (u.mWifiMulticastTimer != null) {
5014 out.writeInt(1);
5015 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5016 } else {
5017 out.writeInt(0);
5018 }
5019 if (u.mAudioTurnedOnTimer != null) {
5020 out.writeInt(1);
5021 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5022 } else {
5023 out.writeInt(0);
5024 }
5025 if (u.mVideoTurnedOnTimer != null) {
5026 out.writeInt(1);
5027 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5028 } else {
5029 out.writeInt(0);
5030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005031
Dianne Hackborn617f8772009-03-31 15:04:46 -07005032 if (u.mUserActivityCounters == null) {
5033 out.writeInt(0);
5034 } else {
5035 out.writeInt(1);
5036 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5037 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
5038 }
5039 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 int NW = u.mWakelockStats.size();
5042 out.writeInt(NW);
5043 if (NW > 0) {
5044 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
5045 : u.mWakelockStats.entrySet()) {
5046 out.writeString(ent.getKey());
5047 Uid.Wakelock wl = ent.getValue();
5048 if (wl.mTimerFull != null) {
5049 out.writeInt(1);
5050 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
5051 } else {
5052 out.writeInt(0);
5053 }
5054 if (wl.mTimerPartial != null) {
5055 out.writeInt(1);
5056 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
5057 } else {
5058 out.writeInt(0);
5059 }
5060 if (wl.mTimerWindow != null) {
5061 out.writeInt(1);
5062 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
5063 } else {
5064 out.writeInt(0);
5065 }
5066 }
5067 }
5068
5069 int NSE = u.mSensorStats.size();
5070 out.writeInt(NSE);
5071 if (NSE > 0) {
5072 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
5073 : u.mSensorStats.entrySet()) {
5074 out.writeInt(ent.getKey());
5075 Uid.Sensor se = ent.getValue();
5076 if (se.mTimer != null) {
5077 out.writeInt(1);
5078 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5079 } else {
5080 out.writeInt(0);
5081 }
5082 }
5083 }
5084
5085 int NP = u.mProcessStats.size();
5086 out.writeInt(NP);
5087 if (NP > 0) {
5088 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
5089 : u.mProcessStats.entrySet()) {
5090 out.writeString(ent.getKey());
5091 Uid.Proc ps = ent.getValue();
5092 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005093 out.writeLong(ps.mSystemTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005094 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005095 final int N = ps.mSpeedBins.length;
5096 out.writeInt(N);
5097 for (int i=0; i<N; i++) {
5098 if (ps.mSpeedBins[i] != null) {
5099 out.writeInt(1);
5100 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
5101 } else {
5102 out.writeInt(0);
5103 }
5104 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005105 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005106 }
5107 }
5108
5109 NP = u.mPackageStats.size();
5110 out.writeInt(NP);
5111 if (NP > 0) {
5112 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
5113 : u.mPackageStats.entrySet()) {
5114 out.writeString(ent.getKey());
5115 Uid.Pkg ps = ent.getValue();
5116 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005117 final int NS = ps.mServiceStats.size();
5118 out.writeInt(NS);
5119 if (NS > 0) {
5120 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
5121 : ps.mServiceStats.entrySet()) {
5122 out.writeString(sent.getKey());
5123 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
5124 long time = ss.getStartTimeToNowLocked(NOW);
5125 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005127 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005128 }
5129 }
5130 }
5131 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005132
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005133 out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED));
5134 out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005135 }
5136 }
5137
5138 public void readFromParcel(Parcel in) {
5139 readFromParcelLocked(in);
5140 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005142 void readFromParcelLocked(Parcel in) {
5143 int magic = in.readInt();
5144 if (magic != MAGIC) {
5145 throw new ParcelFormatException("Bad magic number");
5146 }
5147
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005148 readHistory(in);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005150 mStartCount = in.readInt();
5151 mBatteryUptime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005152 mBatteryLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005153 mBatteryRealtime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005154 mBatteryLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005155 mScreenOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005156 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005157 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005158 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i,
5159 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005160 }
5161 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005162 mPhoneOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005163 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Wink Saville52840902011-02-18 12:40:47 -08005164 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005165 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
5166 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005167 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005168 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005169 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005170 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
5171 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005172 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005173 mWifiOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005174 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005175 mGlobalWifiRunning = false;
5176 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005177 mBluetoothOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005178 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005179 mUptime = in.readLong();
5180 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005181 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005182 mRealtime = in.readLong();
5183 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005184 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005185 mOnBattery = in.readInt() != 0;
5186 mOnBatteryInternal = false; // we are no longer really running.
5187 mTrackBatteryPastUptime = in.readLong();
5188 mTrackBatteryUptimeStart = in.readLong();
5189 mTrackBatteryPastRealtime = in.readLong();
5190 mTrackBatteryRealtimeStart = in.readLong();
5191 mUnpluggedBatteryUptime = in.readLong();
5192 mUnpluggedBatteryRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005193 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005194 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005195 mLowDischargeAmountSinceCharge = in.readInt();
5196 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005197 mDischargeAmountScreenOn = in.readInt();
5198 mDischargeAmountScreenOnSinceCharge = in.readInt();
5199 mDischargeAmountScreenOff = in.readInt();
5200 mDischargeAmountScreenOffSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005201 mLastWriteTime = in.readLong();
5202
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005203 mMobileDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005204 mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005205 mMobileDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005206 mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005207 mTotalDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005208 mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005209 mTotalDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005210 mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005211
5212 mRadioDataUptime = in.readLong();
5213 mRadioDataStart = -1;
5214
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005215 mBluetoothPingCount = in.readInt();
5216 mBluetoothPingStart = -1;
5217
Evan Millarc64edde2009-04-18 12:26:32 -07005218 mKernelWakelockStats.clear();
5219 int NKW = in.readInt();
5220 for (int ikw = 0; ikw < NKW; ikw++) {
5221 if (in.readInt() != 0) {
5222 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005223 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07005224 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
5225 mKernelWakelockStats.put(wakelockName, kwlt);
5226 }
5227 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005229 mPartialTimers.clear();
5230 mFullTimers.clear();
5231 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005232 mWifiRunningTimers.clear();
5233 mFullWifiLockTimers.clear();
5234 mScanWifiLockTimers.clear();
5235 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005236
Amith Yamasanie43530a2009-08-21 13:11:37 -07005237 sNumSpeedSteps = in.readInt();
5238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005239 int numUids = in.readInt();
5240 mUidStats.clear();
5241 for (int i = 0; i < numUids; i++) {
5242 int uid = in.readInt();
5243 Uid u = new Uid(uid);
5244 u.readFromParcelLocked(mUnpluggables, in);
5245 mUidStats.append(uid, u);
5246 }
5247 }
5248
5249 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005250 writeToParcelLocked(out, true, flags);
5251 }
5252
5253 public void writeToParcelWithoutUids(Parcel out, int flags) {
5254 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005255 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005256
5257 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005258 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005259 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
5260 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
5261 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
5262 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005264 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005265
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005266 writeHistory(out);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005268 out.writeInt(mStartCount);
5269 out.writeLong(mBatteryUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005270 out.writeLong(mBatteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005271 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005272 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5273 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
5274 }
5275 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Wink Saville52840902011-02-18 12:40:47 -08005277 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005278 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
5279 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005280 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005281 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5282 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
5283 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005284 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005285 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005286 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287 out.writeLong(mUptime);
5288 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005289 out.writeLong(mRealtime);
5290 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005291 out.writeInt(mOnBattery ? 1 : 0);
5292 out.writeLong(batteryUptime);
5293 out.writeLong(mTrackBatteryUptimeStart);
5294 out.writeLong(batteryRealtime);
5295 out.writeLong(mTrackBatteryRealtimeStart);
5296 out.writeLong(mUnpluggedBatteryUptime);
5297 out.writeLong(mUnpluggedBatteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005298 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005299 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005300 out.writeInt(mLowDischargeAmountSinceCharge);
5301 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005302 out.writeInt(mDischargeAmountScreenOn);
5303 out.writeInt(mDischargeAmountScreenOnSinceCharge);
5304 out.writeInt(mDischargeAmountScreenOff);
5305 out.writeInt(mDischargeAmountScreenOffSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005306 out.writeLong(mLastWriteTime);
5307
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005308 out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5309 out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED));
5310 out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5311 out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED));
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005312
5313 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005314 out.writeLong(getRadioDataUptime());
5315
5316 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005317
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005318 if (inclUids) {
5319 out.writeInt(mKernelWakelockStats.size());
5320 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5321 SamplingTimer kwlt = ent.getValue();
5322 if (kwlt != null) {
5323 out.writeInt(1);
5324 out.writeString(ent.getKey());
5325 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
5326 } else {
5327 out.writeInt(0);
5328 }
Evan Millarc64edde2009-04-18 12:26:32 -07005329 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005330 } else {
5331 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07005332 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005333
5334 out.writeInt(sNumSpeedSteps);
5335
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005336 if (inclUids) {
5337 int size = mUidStats.size();
5338 out.writeInt(size);
5339 for (int i = 0; i < size; i++) {
5340 out.writeInt(mUidStats.keyAt(i));
5341 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005343 uid.writeToParcelLocked(out, batteryRealtime);
5344 }
5345 } else {
5346 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005347 }
5348 }
5349
5350 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
5351 new Parcelable.Creator<BatteryStatsImpl>() {
5352 public BatteryStatsImpl createFromParcel(Parcel in) {
5353 return new BatteryStatsImpl(in);
5354 }
5355
5356 public BatteryStatsImpl[] newArray(int size) {
5357 return new BatteryStatsImpl[size];
5358 }
5359 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005360
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005361 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005362 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005363 Printer pr = new PrintWriterPrinter(pw);
5364 pr.println("*** Screen timer:");
5365 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005366 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005367 pr.println("*** Screen brightness #" + i + ":");
5368 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005369 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005370 pr.println("*** Input event counter:");
5371 mInputEventCounter.logState(pr, " ");
5372 pr.println("*** Phone timer:");
5373 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08005374 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005375 pr.println("*** Signal strength #" + i + ":");
5376 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005377 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005378 pr.println("*** Signal scanning :");
5379 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005380 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005381 pr.println("*** Data connection type #" + i + ":");
5382 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005383 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005384 pr.println("*** Wifi timer:");
5385 mWifiOnTimer.logState(pr, " ");
5386 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005387 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005388 pr.println("*** Bluetooth timer:");
5389 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005390 }
5391 super.dumpLocked(pw);
5392 }
5393}