blob: 12687a130e3f76c81bddc55e3304e66440374db4 [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 Hackborn0ffc9882011-04-13 18:15:56 -070039import android.util.LogWriter;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070040import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070042import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.util.SparseArray;
44
Amith Yamasani3718aaa2009-06-09 06:32:35 -070045import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import java.io.File;
47import java.io.FileInputStream;
48import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070049import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070051import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import java.util.ArrayList;
53import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070054import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070055import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070057import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070058import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059
60/**
61 * All information we are collecting about things that can happen that impact
62 * battery life. All times are represented in microseconds except where indicated
63 * otherwise.
64 */
65public final class BatteryStatsImpl extends BatteryStats {
66 private static final String TAG = "BatteryStatsImpl";
67 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070068 private static final boolean DEBUG_HISTORY = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070071 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
73 // Current on-disk Parcel version
Dianne Hackborn1fadab52011-04-14 17:57:33 -070074 private static final int VERSION = 60;
Amith Yamasanie43530a2009-08-21 13:11:37 -070075
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070076 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070077 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070078
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070079 // No, really, THIS is the maximum number of items we will record in the history.
80 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
81
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080082 // The maximum number of names wakelocks we will keep track of
83 // per uid; once the limit is reached, we batch the remaining wakelocks
84 // in to one common name.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070085 private static final int MAX_WAKELOCKS_PER_UID = 30;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070086
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080087 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070088
Amith Yamasanie43530a2009-08-21 13:11:37 -070089 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070091 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092
Dianne Hackborn0d903a82010-09-07 23:51:03 -070093 static final int MSG_UPDATE_WAKELOCKS = 1;
94 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -070095 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070096
97 public interface BatteryCallback {
98 public void batteryNeedsCpuUpdate();
99 public void batteryPowerChanged(boolean onBattery);
100 }
101
102 final class MyHandler extends Handler {
103 @Override
104 public void handleMessage(Message msg) {
105 BatteryCallback cb = mCallback;
106 switch (msg.what) {
107 case MSG_UPDATE_WAKELOCKS:
108 if (cb != null) {
109 cb.batteryNeedsCpuUpdate();
110 }
111 break;
112 case MSG_REPORT_POWER_CHANGE:
113 if (cb != null) {
114 cb.batteryPowerChanged(msg.arg1 != 0);
115 }
116 break;
117 }
118 }
119 }
120
121 private final MyHandler mHandler;
122
123 private BatteryCallback mCallback;
124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 /**
126 * The statistics we have collected organized by uids.
127 */
128 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
129 new SparseArray<BatteryStatsImpl.Uid>();
130
131 // A set of pools of currently active timers. When a timer is queried, we will divide the
132 // elapsed time by the number of active timers to arrive at that timer's share of the time.
133 // In order to do this, we must refresh each timer whenever the number of active timers
134 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700135 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
136 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
137 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
138 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
139 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700140 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
141 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
142 final ArrayList<StopwatchTimer> mScanWifiLockTimers = new ArrayList<StopwatchTimer>();
143 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700145 // Last partial timers we use for distributing CPU usage.
146 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 // These are the objects that will want to do something when the device
149 // is unplugged from power.
150 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700151
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700152 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700153
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700154 long mHistoryBaseTime;
155 boolean mHaveBatteryLevel = false;
156 boolean mRecordingHistory = true;
157 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700158
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700159 static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
160 static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700161 final Parcel mHistoryBuffer = Parcel.obtain();
162 final HistoryItem mHistoryLastWritten = new HistoryItem();
163 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700164 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700165 int mHistoryBufferLastPos = -1;
166 boolean mHistoryOverflow = false;
167 long mLastHistoryTime = 0;
168
169 final HistoryItem mHistoryCur = new HistoryItem();
170
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700171 HistoryItem mHistory;
172 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700173 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700174 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700175
176 private HistoryItem mHistoryIterator;
177 private boolean mReadOverflow;
178 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 int mStartCount;
181
182 long mBatteryUptime;
183 long mBatteryLastUptime;
184 long mBatteryRealtime;
185 long mBatteryLastRealtime;
186
187 long mUptime;
188 long mUptimeStart;
189 long mLastUptime;
190 long mRealtime;
191 long mRealtimeStart;
192 long mLastRealtime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700195 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700196
Dianne Hackborn617f8772009-03-31 15:04:46 -0700197 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700198 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700199
Dianne Hackborn617f8772009-03-31 15:04:46 -0700200 Counter mInputEventCounter;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700203 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700204
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700205 boolean mAudioOn;
206 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700207
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700208 boolean mVideoOn;
209 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700210
Dianne Hackborn627bba72009-03-24 22:32:56 -0700211 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800212 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700213 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800214 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700215
216 StopwatchTimer mPhoneSignalScanningTimer;
217
Dianne Hackborn627bba72009-03-24 22:32:56 -0700218 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700219 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700220 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700221
The Android Open Source Project10592532009-03-18 17:39:46 -0700222 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700223 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700224 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700225
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700226 boolean mGlobalWifiRunning;
227 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700228
The Android Open Source Project10592532009-03-18 17:39:46 -0700229 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700230 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700231
232 /** Bluetooth headset object */
233 BluetoothHeadset mBtHeadset;
234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 /**
236 * These provide time bases that discount the time the device is plugged
237 * in to power.
238 */
239 boolean mOnBattery;
240 boolean mOnBatteryInternal;
241 long mTrackBatteryPastUptime;
242 long mTrackBatteryUptimeStart;
243 long mTrackBatteryPastRealtime;
244 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 long mUnpluggedBatteryUptime;
247 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700248
The Android Open Source Project10592532009-03-18 17:39:46 -0700249 /*
250 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
251 */
Evan Millar633a1742009-04-02 16:36:33 -0700252 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700253 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700254 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700255 int mLowDischargeAmountSinceCharge;
256 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800257 int mDischargeScreenOnUnplugLevel;
258 int mDischargeScreenOffUnplugLevel;
259 int mDischargeAmountScreenOn;
260 int mDischargeAmountScreenOnSinceCharge;
261 int mDischargeAmountScreenOff;
262 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700265
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700266 // Mobile data transferred while on battery
267 private long[] mMobileDataTx = new long[4];
268 private long[] mMobileDataRx = new long[4];
269 private long[] mTotalDataTx = new long[4];
270 private long[] mTotalDataRx = new long[4];
271
272 private long mRadioDataUptime;
273 private long mRadioDataStart;
274
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700275 private int mBluetoothPingCount;
276 private int mBluetoothPingStart = -1;
277
Amith Yamasanif37447b2009-10-08 18:28:01 -0700278 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800279 private int mPhoneServiceStateRaw = -1;
280 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700281
Evan Millarc64edde2009-04-18 12:26:32 -0700282 /*
283 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
284 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700285 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700286 new HashMap<String, SamplingTimer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700287
Evan Millarc64edde2009-04-18 12:26:32 -0700288 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
289 return mKernelWakelockStats;
290 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700291
Evan Millarc64edde2009-04-18 12:26:32 -0700292 private static int sKernelWakelockUpdateVersion = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700293
Evan Millarc64edde2009-04-18 12:26:32 -0700294 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
295 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
296 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
297 Process.PROC_TAB_TERM,
298 Process.PROC_TAB_TERM,
299 Process.PROC_TAB_TERM,
300 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
301 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700302
Evan Millarc64edde2009-04-18 12:26:32 -0700303 private final String[] mProcWakelocksName = new String[3];
304 private final long[] mProcWakelocksData = new long[3];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700305
Evan Millarc64edde2009-04-18 12:26:32 -0700306 /*
307 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
308 * to mKernelWakelockStats.
309 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700310 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700311 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700313 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 // For debugging
316 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700317 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700318 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 }
320
321 public static interface Unpluggable {
322 void unplug(long batteryUptime, long batteryRealtime);
323 void plug(long batteryUptime, long batteryRealtime);
324 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700327 * State for keeping track of counting information.
328 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700329 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700330 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700331 final ArrayList<Unpluggable> mUnpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700332 int mLoadedCount;
333 int mLastCount;
334 int mUnpluggedCount;
335 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700336
Dianne Hackborn617f8772009-03-31 15:04:46 -0700337 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700338 mUnpluggables = unpluggables;
Christopher Tate4cee7252010-03-19 14:50:40 -0700339 mPluggedCount = in.readInt();
340 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700341 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700342 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700343 mUnpluggedCount = in.readInt();
344 unpluggables.add(this);
345 }
346
347 Counter(ArrayList<Unpluggable> unpluggables) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700348 mUnpluggables = unpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700349 unpluggables.add(this);
350 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700351
Dianne Hackborn617f8772009-03-31 15:04:46 -0700352 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700353 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700354 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700355 out.writeInt(mUnpluggedCount);
356 }
357
358 public void unplug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700359 mUnpluggedCount = mPluggedCount;
360 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700361 }
362
363 public void plug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700364 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700365 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700366
Dianne Hackborn617f8772009-03-31 15:04:46 -0700367 /**
368 * Writes a possibly null Counter to a Parcel.
369 *
370 * @param out the Parcel to be written to.
371 * @param counter a Counter, or null.
372 */
373 public static void writeCounterToParcel(Parcel out, Counter counter) {
374 if (counter == null) {
375 out.writeInt(0); // indicates null
376 return;
377 }
378 out.writeInt(1); // indicates non-null
379
380 counter.writeToParcel(out);
381 }
382
383 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700384 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700385 int val;
386 if (which == STATS_LAST) {
387 val = mLastCount;
388 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700389 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700390 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700391 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700392 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700393 val -= mLoadedCount;
394 }
395 }
396
397 return val;
398 }
399
400 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700401 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700402 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
403 + " mUnpluggedCount=" + mUnpluggedCount
404 + " mPluggedCount=" + mPluggedCount);
405 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700406
Christopher Tate4cee7252010-03-19 14:50:40 -0700407 void stepAtomic() {
408 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700409 }
410
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700411 /**
412 * Clear state of this counter.
413 */
414 void reset(boolean detachIfReset) {
415 mCount.set(0);
416 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
417 if (detachIfReset) {
418 detach();
419 }
420 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700421
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700422 void detach() {
423 mUnpluggables.remove(this);
424 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700425
Dianne Hackborn617f8772009-03-31 15:04:46 -0700426 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700427 int count = mCount.get();
428 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700429 }
430
431 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700432 mLoadedCount = in.readInt();
433 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700434 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700435 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700436 }
437 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700438
439 public static class SamplingCounter extends Counter {
440
441 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
442 super(unpluggables, in);
443 }
444
445 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
446 super(unpluggables);
447 }
448
Christopher Tate4cee7252010-03-19 14:50:40 -0700449 public void addCountAtomic(long count) {
450 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700451 }
452 }
453
Dianne Hackborn617f8772009-03-31 15:04:46 -0700454 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 * State for keeping track of timing information.
456 */
Evan Millarc64edde2009-04-18 12:26:32 -0700457 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 final int mType;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700459 final ArrayList<Unpluggable> mUnpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 int mCount;
462 int mLoadedCount;
463 int mLastCount;
464 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 // Times are in microseconds for better accuracy when dividing by the
467 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 /**
470 * The total time we have accumulated since the start of the original
471 * boot, to the last time something interesting happened in the
472 * current run.
473 */
474 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 /**
477 * The total time we loaded for the previous runs. Subtract this from
478 * mTotalTime to find the time for the current run of the system.
479 */
480 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 /**
483 * The run time of the last run of the system, as loaded from the
484 * saved data.
485 */
486 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 /**
489 * The value of mTotalTime when unplug() was last called. Subtract
490 * this from mTotalTime to find the time since the last unplug from
491 * power.
492 */
493 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700494
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700495 /**
496 * Constructs from a parcel.
497 * @param type
498 * @param unpluggables
499 * @param powerType
500 * @param in
501 */
Evan Millarc64edde2009-04-18 12:26:32 -0700502 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700504 mUnpluggables = unpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 mCount = in.readInt();
507 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700508 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 mUnpluggedCount = in.readInt();
510 mTotalTime = in.readLong();
511 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700512 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 mUnpluggedTime = in.readLong();
514 unpluggables.add(this);
515 }
516
Evan Millarc64edde2009-04-18 12:26:32 -0700517 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700519 mUnpluggables = unpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 unpluggables.add(this);
521 }
Evan Millarc64edde2009-04-18 12:26:32 -0700522
523 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700524
Evan Millarc64edde2009-04-18 12:26:32 -0700525 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700526
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700527 /**
528 * Clear state of this timer. Returns true if the timer is inactive
529 * so can be completely dropped.
530 */
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700531 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700532 mTotalTime = mLoadedTime = mLastTime = 0;
533 mCount = mLoadedCount = mLastCount = 0;
534 if (detachIfReset) {
535 detach();
536 }
537 return true;
538 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700539
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700540 void detach() {
541 mUnpluggables.remove(this);
542 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 public void writeToParcel(Parcel out, long batteryRealtime) {
545 out.writeInt(mCount);
546 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 out.writeInt(mUnpluggedCount);
548 out.writeLong(computeRunTimeLocked(batteryRealtime));
549 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 out.writeLong(mUnpluggedTime);
551 }
552
553 public void unplug(long batteryUptime, long batteryRealtime) {
554 if (DEBUG && mType < 0) {
555 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
556 + " old mUnpluggedTime=" + mUnpluggedTime
557 + " old mUnpluggedCount=" + mUnpluggedCount);
558 }
559 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
560 mUnpluggedCount = mCount;
561 if (DEBUG && mType < 0) {
562 Log.v(TAG, "unplug #" + mType
563 + ": new mUnpluggedTime=" + mUnpluggedTime
564 + " new mUnpluggedCount=" + mUnpluggedCount);
565 }
566 }
567
568 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700569 if (DEBUG && mType < 0) {
570 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
571 + " old mTotalTime=" + mTotalTime);
572 }
573 mTotalTime = computeRunTimeLocked(batteryRealtime);
574 mCount = computeCurrentCountLocked();
575 if (DEBUG && mType < 0) {
576 Log.v(TAG, "plug #" + mType
577 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 }
579 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 /**
582 * Writes a possibly null Timer to a Parcel.
583 *
584 * @param out the Parcel to be written to.
585 * @param timer a Timer, or null.
586 */
587 public static void writeTimerToParcel(Parcel out, Timer timer,
588 long batteryRealtime) {
589 if (timer == null) {
590 out.writeInt(0); // indicates null
591 return;
592 }
593 out.writeInt(1); // indicates non-null
594
595 timer.writeToParcel(out, batteryRealtime);
596 }
597
598 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700599 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 long val;
601 if (which == STATS_LAST) {
602 val = mLastTime;
603 } else {
604 val = computeRunTimeLocked(batteryRealtime);
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 -= mUnpluggedTime;
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 -= mLoadedTime;
609 }
610 }
611
612 return val;
613 }
614
615 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700616 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 int val;
618 if (which == STATS_LAST) {
619 val = mLastCount;
620 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700621 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700622 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700624 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 val -= mLoadedCount;
626 }
627 }
628
629 return val;
630 }
631
Dianne Hackborn627bba72009-03-24 22:32:56 -0700632 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700633 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
635 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700636 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700638 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700640 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700641
642
Evan Millarc64edde2009-04-18 12:26:32 -0700643 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
644 long runTime = computeRunTimeLocked(batteryRealtime);
645 // Divide by 1000 for backwards compatibility
646 out.writeLong((runTime + 500) / 1000);
Evan Millarc64edde2009-04-18 12:26:32 -0700647 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -0700648 }
649
650 void readSummaryFromParcelLocked(Parcel in) {
651 // Multiply by 1000 for backwards compatibility
652 mTotalTime = mLoadedTime = in.readLong() * 1000;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700653 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700654 mUnpluggedTime = mTotalTime;
655 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700656 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700657 mUnpluggedCount = mCount;
658 }
659 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700660
Evan Millarc64edde2009-04-18 12:26:32 -0700661 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700662
Evan Millarc64edde2009-04-18 12:26:32 -0700663 /**
664 * The most recent reported count from /proc/wakelocks.
665 */
666 int mCurrentReportedCount;
667
668 /**
669 * The reported count from /proc/wakelocks when unplug() was last
670 * called.
671 */
672 int mUnpluggedReportedCount;
673
674 /**
675 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700676 */
Evan Millarc64edde2009-04-18 12:26:32 -0700677 long mCurrentReportedTotalTime;
678
679
680 /**
681 * The reported total_time from /proc/wakelocks when unplug() was last
682 * called.
683 */
684 long mUnpluggedReportedTotalTime;
685
686 /**
687 * Whether we are currently in a discharge cycle.
688 */
689 boolean mInDischarge;
690
691 /**
692 * Whether we are currently recording reported values.
693 */
694 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700695
Evan Millarc64edde2009-04-18 12:26:32 -0700696 /*
697 * A sequnce counter, incremented once for each update of the stats.
698 */
699 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700700
Evan Millarc64edde2009-04-18 12:26:32 -0700701 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
702 super(0, unpluggables, in);
703 mCurrentReportedCount = in.readInt();
704 mUnpluggedReportedCount = in.readInt();
705 mCurrentReportedTotalTime = in.readLong();
706 mUnpluggedReportedTotalTime = in.readLong();
707 mTrackingReportedValues = in.readInt() == 1;
708 mInDischarge = inDischarge;
709 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700710
711 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
Evan Millarc64edde2009-04-18 12:26:32 -0700712 boolean trackReportedValues) {
713 super(0, unpluggables);
714 mTrackingReportedValues = trackReportedValues;
715 mInDischarge = inDischarge;
716 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700717
Evan Millarc64edde2009-04-18 12:26:32 -0700718 public void setStale() {
719 mTrackingReportedValues = false;
720 mUnpluggedReportedTotalTime = 0;
721 mUnpluggedReportedCount = 0;
722 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700723
Evan Millarc64edde2009-04-18 12:26:32 -0700724 public void setUpdateVersion(int version) {
725 mUpdateVersion = version;
726 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700727
Evan Millarc64edde2009-04-18 12:26:32 -0700728 public int getUpdateVersion() {
729 return mUpdateVersion;
730 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700731
Evan Millarc64edde2009-04-18 12:26:32 -0700732 public void updateCurrentReportedCount(int count) {
733 if (mInDischarge && mUnpluggedReportedCount == 0) {
734 // Updating the reported value for the first time.
735 mUnpluggedReportedCount = count;
736 // If we are receiving an update update mTrackingReportedValues;
737 mTrackingReportedValues = true;
738 }
739 mCurrentReportedCount = count;
740 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700741
Evan Millarc64edde2009-04-18 12:26:32 -0700742 public void updateCurrentReportedTotalTime(long totalTime) {
743 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
744 // Updating the reported value for the first time.
745 mUnpluggedReportedTotalTime = totalTime;
746 // If we are receiving an update update mTrackingReportedValues;
747 mTrackingReportedValues = true;
748 }
749 mCurrentReportedTotalTime = totalTime;
750 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700751
Evan Millarc64edde2009-04-18 12:26:32 -0700752 public void unplug(long batteryUptime, long batteryRealtime) {
753 super.unplug(batteryUptime, batteryRealtime);
754 if (mTrackingReportedValues) {
755 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
756 mUnpluggedReportedCount = mCurrentReportedCount;
757 }
758 mInDischarge = true;
759 }
760
761 public void plug(long batteryUptime, long batteryRealtime) {
762 super.plug(batteryUptime, batteryRealtime);
763 mInDischarge = false;
764 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700765
Evan Millarc64edde2009-04-18 12:26:32 -0700766 public void logState(Printer pw, String prefix) {
767 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700768 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -0700769 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
770 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
771 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
772 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700773
Evan Millarc64edde2009-04-18 12:26:32 -0700774 protected long computeRunTimeLocked(long curBatteryRealtime) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700775 return mTotalTime + (mInDischarge && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -0700776 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
777 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700778
Evan Millarc64edde2009-04-18 12:26:32 -0700779 protected int computeCurrentCountLocked() {
780 return mCount + (mInDischarge && mTrackingReportedValues
781 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
782 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700783
Evan Millarc64edde2009-04-18 12:26:32 -0700784 public void writeToParcel(Parcel out, long batteryRealtime) {
785 super.writeToParcel(out, batteryRealtime);
786 out.writeInt(mCurrentReportedCount);
787 out.writeInt(mUnpluggedReportedCount);
788 out.writeLong(mCurrentReportedTotalTime);
789 out.writeLong(mUnpluggedReportedTotalTime);
790 out.writeInt(mTrackingReportedValues ? 1 : 0);
791 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700792
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700793 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
794 super.reset(stats, detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700795 setStale();
796 return true;
797 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700798
Evan Millarc64edde2009-04-18 12:26:32 -0700799 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
800 super.writeSummaryFromParcelLocked(out, batteryRealtime);
801 out.writeLong(mCurrentReportedTotalTime);
802 out.writeInt(mCurrentReportedCount);
803 out.writeInt(mTrackingReportedValues ? 1 : 0);
804 }
805
806 void readSummaryFromParcelLocked(Parcel in) {
807 super.readSummaryFromParcelLocked(in);
808 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
809 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
810 mTrackingReportedValues = in.readInt() == 1;
811 }
812 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700813
Evan Millarc64edde2009-04-18 12:26:32 -0700814 /**
815 * State for keeping track of timing information.
816 */
817 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700818 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -0700819 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700820
Evan Millarc64edde2009-04-18 12:26:32 -0700821 int mNesting;
822
Evan Millarc64edde2009-04-18 12:26:32 -0700823 /**
824 * The last time at which we updated the timer. If mNesting is > 0,
825 * subtract this from the current battery time to find the amount of
826 * time we have been running since we last computed an update.
827 */
828 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700829
Evan Millarc64edde2009-04-18 12:26:32 -0700830 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700831 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -0700832 * was actually held for an interesting duration.
833 */
834 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700835
Amith Yamasanif37447b2009-10-08 18:28:01 -0700836 long mTimeout;
837
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700838 /**
839 * For partial wake locks, keep track of whether we are in the list
840 * to consume CPU cycles.
841 */
842 boolean mInList;
843
844 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700845 ArrayList<Unpluggable> unpluggables, Parcel in) {
846 super(type, unpluggables, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700847 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700848 mTimerPool = timerPool;
849 mUpdateTime = in.readLong();
850 }
851
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700852 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700853 ArrayList<Unpluggable> unpluggables) {
854 super(type, unpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700855 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700856 mTimerPool = timerPool;
857 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700858
Amith Yamasanif37447b2009-10-08 18:28:01 -0700859 void setTimeout(long timeout) {
860 mTimeout = timeout;
861 }
862
Evan Millarc64edde2009-04-18 12:26:32 -0700863 public void writeToParcel(Parcel out, long batteryRealtime) {
864 super.writeToParcel(out, batteryRealtime);
865 out.writeLong(mUpdateTime);
866 }
867
868 public void plug(long batteryUptime, long batteryRealtime) {
869 if (mNesting > 0) {
870 if (DEBUG && mType < 0) {
871 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
872 }
873 super.plug(batteryUptime, batteryRealtime);
874 mUpdateTime = batteryRealtime;
875 if (DEBUG && mType < 0) {
876 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
877 }
878 }
879 }
880
881 public void logState(Printer pw, String prefix) {
882 super.logState(pw, prefix);
883 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 + " mAcquireTime=" + mAcquireTime);
885 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 void startRunningLocked(BatteryStatsImpl stats) {
888 if (mNesting++ == 0) {
889 mUpdateTime = stats.getBatteryRealtimeLocked(
890 SystemClock.elapsedRealtime() * 1000);
891 if (mTimerPool != null) {
892 // Accumulate time to all currently active timers before adding
893 // this new one to the pool.
894 refreshTimersLocked(stats, mTimerPool);
895 // Add this timer to the active pool
896 mTimerPool.add(this);
897 }
898 // Increment the count
899 mCount++;
900 mAcquireTime = mTotalTime;
901 if (DEBUG && mType < 0) {
902 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
903 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
904 + " mAcquireTime=" + mAcquireTime);
905 }
906 }
907 }
908
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700909 boolean isRunningLocked() {
910 return mNesting > 0;
911 }
912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800913 void stopRunningLocked(BatteryStatsImpl stats) {
914 // Ignore attempt to stop a timer that isn't running
915 if (mNesting == 0) {
916 return;
917 }
918 if (--mNesting == 0) {
919 if (mTimerPool != null) {
920 // Accumulate time to all active counters, scaled by the total
921 // active in the pool, before taking this one out of the pool.
922 refreshTimersLocked(stats, mTimerPool);
923 // Remove this timer from the active pool
924 mTimerPool.remove(this);
925 } else {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700926 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
928 mNesting = 1;
929 mTotalTime = computeRunTimeLocked(batteryRealtime);
930 mNesting = 0;
931 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 if (DEBUG && mType < 0) {
934 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
935 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
936 + " mAcquireTime=" + mAcquireTime);
937 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 if (mTotalTime == mAcquireTime) {
940 // If there was no change in the time, then discard this
941 // count. A somewhat cheezy strategy, but hey.
942 mCount--;
943 }
944 }
945 }
946
947 // Update the total time for all other running Timers with the same type as this Timer
948 // due to a change in timer count
949 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700950 final ArrayList<StopwatchTimer> pool) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700951 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
953 final int N = pool.size();
954 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700955 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 long heldTime = batteryRealtime - t.mUpdateTime;
957 if (heldTime > 0) {
958 t.mTotalTime += heldTime / N;
959 }
960 t.mUpdateTime = batteryRealtime;
961 }
962 }
963
Evan Millarc64edde2009-04-18 12:26:32 -0700964 @Override
965 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700966 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
967 curBatteryRealtime = mUpdateTime + mTimeout;
968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 return mTotalTime + (mNesting > 0
970 ? (curBatteryRealtime - mUpdateTime)
971 / (mTimerPool != null ? mTimerPool.size() : 1)
972 : 0);
973 }
974
Evan Millarc64edde2009-04-18 12:26:32 -0700975 @Override
976 protected int computeCurrentCountLocked() {
977 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 }
979
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700980 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700981 boolean canDetach = mNesting <= 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700982 super.reset(stats, canDetach && detachIfReset);
983 if (mNesting > 0) {
984 mUpdateTime = stats.getBatteryRealtimeLocked(
985 SystemClock.elapsedRealtime() * 1000);
986 }
987 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700988 return canDetach;
989 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700990
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700991 void detach() {
992 super.detach();
993 if (mTimerPool != null) {
994 mTimerPool.remove(this);
995 }
996 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700997
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -0700999 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 mNesting = 0;
1001 }
1002 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001003
Evan Millarc64edde2009-04-18 12:26:32 -07001004 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001005
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001006 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -07001007 int len;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001008
Evan Millarc64edde2009-04-18 12:26:32 -07001009 try {
1010 FileInputStream is = new FileInputStream("/proc/wakelocks");
1011 len = is.read(buffer);
1012 is.close();
1013
1014 if (len > 0) {
1015 int i;
1016 for (i=0; i<len; i++) {
1017 if (buffer[i] == '\0') {
1018 len = i;
1019 break;
1020 }
1021 }
1022 }
1023 } catch (java.io.FileNotFoundException e) {
1024 return null;
1025 } catch (java.io.IOException e) {
1026 return null;
1027 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001028
Evan Millarc64edde2009-04-18 12:26:32 -07001029 return parseProcWakelocks(buffer, len);
1030 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001031
Evan Millarc64edde2009-04-18 12:26:32 -07001032 private final Map<String, KernelWakelockStats> parseProcWakelocks(
1033 byte[] wlBuffer, int len) {
1034 String name;
1035 int count;
1036 long totalTime;
1037 int startIndex, endIndex;
1038 int numUpdatedWlNames = 0;
1039
1040 // Advance past the first line.
1041 int i;
1042 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1043 startIndex = endIndex = i + 1;
1044
1045 synchronized(this) {
1046 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001047
Evan Millarc64edde2009-04-18 12:26:32 -07001048 sKernelWakelockUpdateVersion++;
1049 while (endIndex < len) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001050 for (endIndex=startIndex;
1051 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
Evan Millarc64edde2009-04-18 12:26:32 -07001052 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001053 endIndex++; // endIndex is an exclusive upper bound.
1054 // Don't go over the end of the buffer, Process.parseProcLine might
1055 // write to wlBuffer[endIndex]
1056 if (endIndex >= (len - 1) ) {
1057 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -07001058 }
Evan Millarc64edde2009-04-18 12:26:32 -07001059
1060 String[] nameStringArray = mProcWakelocksName;
1061 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001062 // Stomp out any bad characters since this is from a circular buffer
1063 // A corruption is seen sometimes that results in the vm crashing
1064 // This should prevent crashes and the line will probably fail to parse
1065 for (int j = startIndex; j < endIndex; j++) {
1066 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1067 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001068 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
1069 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001070
Evan Millarc64edde2009-04-18 12:26:32 -07001071 name = nameStringArray[0];
1072 count = (int) wlData[1];
1073 // convert nanoseconds to microseconds with rounding.
1074 totalTime = (wlData[2] + 500) / 1000;
1075
Amith Yamasani53b707b2009-09-30 11:05:30 -07001076 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001077 if (!m.containsKey(name)) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001078 m.put(name, new KernelWakelockStats(count, totalTime,
Evan Millarc64edde2009-04-18 12:26:32 -07001079 sKernelWakelockUpdateVersion));
1080 numUpdatedWlNames++;
1081 } else {
1082 KernelWakelockStats kwlStats = m.get(name);
1083 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1084 kwlStats.mCount += count;
1085 kwlStats.mTotalTime += totalTime;
1086 } else {
1087 kwlStats.mCount = count;
1088 kwlStats.mTotalTime = totalTime;
1089 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1090 numUpdatedWlNames++;
1091 }
1092 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001093 }
Evan Millarc64edde2009-04-18 12:26:32 -07001094 startIndex = endIndex;
1095 }
1096
1097 if (m.size() != numUpdatedWlNames) {
1098 // Don't report old data.
1099 Iterator<KernelWakelockStats> itr = m.values().iterator();
1100 while (itr.hasNext()) {
1101 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1102 itr.remove();
1103 }
1104 }
1105 }
1106 return m;
1107 }
1108 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001109
Evan Millarc64edde2009-04-18 12:26:32 -07001110 private class KernelWakelockStats {
1111 public int mCount;
1112 public long mTotalTime;
1113 public int mVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001114
Evan Millarc64edde2009-04-18 12:26:32 -07001115 KernelWakelockStats(int count, long totalTime, int version) {
1116 mCount = count;
1117 mTotalTime = totalTime;
1118 mVersion = version;
1119 }
1120 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001121
Evan Millarc64edde2009-04-18 12:26:32 -07001122 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001123 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001124 * doesn't already exist.
1125 */
1126 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1127 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1128 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001129 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07001130 true /* track reported values */);
1131 mKernelWakelockStats.put(name, kwlt);
1132 }
1133 return kwlt;
1134 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001135
1136 private void doDataPlug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001137 dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED];
1138 dataTransfer[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001139 }
1140
1141 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001142 dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001143 }
1144
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001145 /**
1146 * Radio uptime in microseconds when transferring data. This value is very approximate.
1147 * @return
1148 */
1149 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001150 try {
1151 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
1152 if (!awakeTimeFile.exists()) return 0;
1153 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
1154 String line = br.readLine();
1155 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001156 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001157 } catch (NumberFormatException nfe) {
1158 // Nothing
1159 } catch (IOException ioe) {
1160 // Nothing
1161 }
1162 return 0;
1163 }
1164
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001165 /**
1166 * @deprecated use getRadioDataUptime
1167 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001168 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001169 return getRadioDataUptime() / 1000;
1170 }
1171
1172 /**
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001173 * Returns the duration that the cell radio was up for data transfers.
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001174 */
1175 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001176 if (mRadioDataStart == -1) {
1177 return mRadioDataUptime;
1178 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001179 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001180 }
1181 }
1182
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001183 private int getCurrentBluetoothPingCount() {
1184 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001185 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1186 if (deviceList.size() > 0) {
1187 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001188 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001189 }
1190 return -1;
1191 }
1192
1193 public int getBluetoothPingCount() {
1194 if (mBluetoothPingStart == -1) {
1195 return mBluetoothPingCount;
1196 } else if (mBtHeadset != null) {
1197 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1198 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001199 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001200 }
1201
1202 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001203 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1204 mBluetoothPingStart = getCurrentBluetoothPingCount();
1205 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001206 mBtHeadset = headset;
1207 }
1208
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001209 int mChangedBufferStates = 0;
1210
1211 void addHistoryBufferLocked(long curTime) {
1212 if (!mHaveBatteryLevel || !mRecordingHistory) {
1213 return;
1214 }
1215
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001216 final long timeDiff = (mHistoryBaseTime+curTime) - mHistoryLastWritten.time;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001217 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001218 && timeDiff < 2000
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001219 && ((mHistoryLastWritten.states^mHistoryCur.states)&mChangedBufferStates) == 0) {
1220 // If the current is the same as the one before, then we no
1221 // longer need the entry.
1222 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
1223 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
1224 mHistoryBufferLastPos = -1;
1225 if (mHistoryLastLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001226 && timeDiff < 500 && mHistoryLastLastWritten.same(mHistoryCur)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001227 // If this results in us returning to the state written
1228 // prior to the last one, then we can just delete the last
1229 // written one and drop the new one. Nothing more to do.
1230 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
1231 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1232 return;
1233 }
1234 mChangedBufferStates |= mHistoryLastWritten.states^mHistoryCur.states;
1235 curTime = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001236 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001237 } else {
1238 mChangedBufferStates = 0;
1239 }
1240
1241 final int dataSize = mHistoryBuffer.dataSize();
1242 if (dataSize >= MAX_HISTORY_BUFFER) {
1243 if (!mHistoryOverflow) {
1244 mHistoryOverflow = true;
1245 addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW);
1246 }
1247
1248 // Once we've reached the maximum number of items, we only
1249 // record changes to the battery level and the most interesting states.
1250 // Once we've reached the maximum maximum number of items, we only
1251 // record changes to the battery level.
1252 if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
1253 (dataSize >= MAX_MAX_HISTORY_BUFFER
1254 || ((mHistoryEnd.states^mHistoryCur.states)
1255 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
1256 return;
1257 }
1258 }
1259
1260 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE);
1261 }
1262
1263 void addHistoryBufferLocked(long curTime, byte cmd) {
1264 int origPos = 0;
1265 if (mIteratingHistory) {
1266 origPos = mHistoryBuffer.dataPosition();
1267 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
1268 }
1269 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
1270 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
1271 mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
1272 mHistoryLastWritten.writeDelta(mHistoryBuffer, mHistoryLastLastWritten);
1273 mLastHistoryTime = curTime;
1274 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
1275 + " now " + mHistoryBuffer.dataPosition()
1276 + " size is now " + mHistoryBuffer.dataSize());
1277 if (mIteratingHistory) {
1278 mHistoryBuffer.setDataPosition(origPos);
1279 }
1280 }
1281
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001282 int mChangedStates = 0;
1283
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001284 void addHistoryRecordLocked(long curTime) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001285 addHistoryBufferLocked(curTime);
1286
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001287 if (!mHaveBatteryLevel || !mRecordingHistory) {
1288 return;
1289 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001290
1291 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001292 // and no states have since the last recorded entry changed and
1293 // are now resetting back to their original value, then just collapse
1294 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001295 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001296 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000)
1297 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001298 // If the current is the same as the one before, then we no
1299 // longer need the entry.
1300 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001301 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500)
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001302 && mHistoryLastEnd.same(mHistoryCur)) {
1303 mHistoryLastEnd.next = null;
1304 mHistoryEnd.next = mHistoryCache;
1305 mHistoryCache = mHistoryEnd;
1306 mHistoryEnd = mHistoryLastEnd;
1307 mHistoryLastEnd = null;
1308 } else {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001309 mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001310 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
1311 }
1312 return;
1313 }
1314
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001315 mChangedStates = 0;
1316
1317 if (mNumHistoryItems == MAX_HISTORY_ITEMS
1318 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001319 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
1320 }
1321
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001322 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
1323 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001324 // record changes to the battery level and the most interesting states.
1325 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001326 // record changes to the battery level.
1327 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001328 == mHistoryCur.batteryLevel &&
1329 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
1330 || ((mHistoryEnd.states^mHistoryCur.states)
1331 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001332 return;
1333 }
1334 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001335
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001336 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
1337 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001338
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001339 void addHistoryRecordLocked(long curTime, byte cmd) {
1340 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001341 if (rec != null) {
1342 mHistoryCache = rec.next;
1343 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001344 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001345 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001346 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001347
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001348 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001349 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001350
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001351 void addHistoryRecordLocked(HistoryItem rec) {
1352 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001353 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001354 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001355 if (mHistoryEnd != null) {
1356 mHistoryEnd.next = rec;
1357 mHistoryEnd = rec;
1358 } else {
1359 mHistory = mHistoryEnd = rec;
1360 }
1361 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001362
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001363 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001364 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001365 if (mHistory != null) {
1366 mHistoryEnd.next = mHistoryCache;
1367 mHistoryCache = mHistory;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001368 mHistory = mHistoryLastEnd = mHistoryEnd = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001369 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001370 mNumHistoryItems = 0;
1371 mHistoryBaseTime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001372 mLastHistoryTime = 0;
1373
1374 mHistoryBuffer.setDataSize(0);
1375 mHistoryBuffer.setDataPosition(0);
1376 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER/2);
1377 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1378 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
1379 mHistoryBufferLastPos = -1;
1380 mHistoryOverflow = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001381 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001382
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001383 public void doUnplugLocked(long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1385 Uid u = mUidStats.valueAt(iu);
Ken Shirriff1719a392009-12-07 15:57:35 -08001386 u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid);
1387 u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1389 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1390 }
1391 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1392 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
1393 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001394 // Track total mobile data
Ken Shirriff1719a392009-12-07 15:57:35 -08001395 doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1396 doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1397 doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1398 doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001399 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001400 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001401 mRadioDataUptime = 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001402 // Track bt headset ping count
1403 mBluetoothPingStart = getCurrentBluetoothPingCount();
1404 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001406
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001407 public void doPlugLocked(long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1409 Uid u = mUidStats.valueAt(iu);
1410 if (u.mStartedTcpBytesReceived >= 0) {
1411 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1412 u.mStartedTcpBytesReceived = -1;
1413 }
1414 if (u.mStartedTcpBytesSent >= 0) {
1415 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1416 u.mStartedTcpBytesSent = -1;
1417 }
1418 }
1419 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1420 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
1421 }
Ken Shirriff1719a392009-12-07 15:57:35 -08001422 doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1423 doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1424 doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1425 doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001426 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001427 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001428 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001429
1430 // Track bt headset ping count
1431 mBluetoothPingCount = getBluetoothPingCount();
1432 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001434
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001435 int mWakeLockNesting;
1436
1437 public void noteStartWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001438 if (type == WAKE_TYPE_PARTIAL) {
1439 // Only care about partial wake locks, since full wake locks
1440 // will be canceled when the user puts the screen to sleep.
1441 if (mWakeLockNesting == 0) {
1442 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
1443 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
1444 + Integer.toHexString(mHistoryCur.states));
1445 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1446 }
1447 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001448 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001449 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001450 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1451 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1452 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1453 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001454 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
1455 }
1456 }
1457
1458 public void noteStopWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001459 if (type == WAKE_TYPE_PARTIAL) {
1460 mWakeLockNesting--;
1461 if (mWakeLockNesting == 0) {
1462 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
1463 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
1464 + Integer.toHexString(mHistoryCur.states));
1465 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1466 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001467 }
1468 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001469 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1470 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1471 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1472 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001473 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
1474 }
1475 }
1476
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001477 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1478 int N = ws.size();
1479 for (int i=0; i<N; i++) {
1480 noteStartWakeLocked(ws.get(i), pid, name, type);
1481 }
1482 }
1483
1484 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1485 int N = ws.size();
1486 for (int i=0; i<N; i++) {
1487 noteStopWakeLocked(ws.get(i), pid, name, type);
1488 }
1489 }
1490
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001491 public int startAddingCpuLocked() {
1492 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
1493
1494 if (mScreenOn) {
1495 return 0;
1496 }
1497
1498 final int N = mPartialTimers.size();
1499 if (N == 0) {
1500 mLastPartialTimers.clear();
1501 return 0;
1502 }
1503
1504 // How many timers should consume CPU? Only want to include ones
1505 // that have already been in the list.
1506 for (int i=0; i<N; i++) {
1507 StopwatchTimer st = mPartialTimers.get(i);
1508 if (st.mInList) {
1509 Uid uid = st.mUid;
1510 // We don't include the system UID, because it so often
1511 // holds wake locks at one request or another of an app.
1512 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1513 return 50;
1514 }
1515 }
1516 }
1517
1518 return 0;
1519 }
1520
1521 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
1522 final int N = mPartialTimers.size();
1523 if (perc != 0) {
1524 int num = 0;
1525 for (int i=0; i<N; i++) {
1526 StopwatchTimer st = mPartialTimers.get(i);
1527 if (st.mInList) {
1528 Uid uid = st.mUid;
1529 // We don't include the system UID, because it so often
1530 // holds wake locks at one request or another of an app.
1531 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1532 num++;
1533 }
1534 }
1535 }
1536 if (num != 0) {
1537 for (int i=0; i<N; i++) {
1538 StopwatchTimer st = mPartialTimers.get(i);
1539 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001540 Uid uid = st.mUid;
1541 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07001542 int myUTime = utime/num;
1543 int mySTime = stime/num;
1544 utime -= myUTime;
1545 stime -= mySTime;
1546 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001547 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
1548 proc.addCpuTimeLocked(myUTime, mySTime);
1549 proc.addSpeedStepTimes(cpuSpeedTimes);
1550 }
1551 }
1552 }
1553 }
1554
1555 // Just in case, collect any lost CPU time.
1556 if (utime != 0 || stime != 0) {
1557 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
1558 if (uid != null) {
1559 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
1560 proc.addCpuTimeLocked(utime, stime);
1561 proc.addSpeedStepTimes(cpuSpeedTimes);
1562 }
1563 }
1564 }
1565
1566 final int NL = mLastPartialTimers.size();
1567 boolean diff = N != NL;
1568 for (int i=0; i<NL && !diff; i++) {
1569 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
1570 }
1571 if (!diff) {
1572 for (int i=0; i<NL; i++) {
1573 mPartialTimers.get(i).mInList = true;
1574 }
1575 return;
1576 }
1577
1578 for (int i=0; i<NL; i++) {
1579 mLastPartialTimers.get(i).mInList = false;
1580 }
1581 mLastPartialTimers.clear();
1582 for (int i=0; i<N; i++) {
1583 StopwatchTimer st = mPartialTimers.get(i);
1584 st.mInList = true;
1585 mLastPartialTimers.add(st);
1586 }
1587 }
1588
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001589 public void noteProcessDiedLocked(int uid, int pid) {
1590 Uid u = mUidStats.get(uid);
1591 if (u != null) {
1592 u.mPids.remove(pid);
1593 }
1594 }
1595
1596 public long getProcessWakeTime(int uid, int pid, long realtime) {
1597 Uid u = mUidStats.get(uid);
1598 if (u != null) {
1599 Uid.Pid p = u.mPids.get(pid);
1600 if (p != null) {
1601 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
1602 }
1603 }
1604 return 0;
1605 }
1606
1607 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
1608 Uid u = mUidStats.get(uid);
1609 if (u != null) {
1610 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
1611 }
1612 }
1613
Dianne Hackborn287952c2010-09-22 22:34:31 -07001614 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
1615 Uid u = mUidStats.get(uid);
1616 if (u != null) {
1617 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
1618 }
1619 }
1620
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001621 int mSensorNesting;
1622
1623 public void noteStartSensorLocked(int uid, int sensor) {
1624 if (mSensorNesting == 0) {
1625 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
1626 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
1627 + Integer.toHexString(mHistoryCur.states));
1628 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1629 }
1630 mSensorNesting++;
1631 getUidStatsLocked(uid).noteStartSensor(sensor);
1632 }
1633
1634 public void noteStopSensorLocked(int uid, int sensor) {
1635 mSensorNesting--;
1636 if (mSensorNesting == 0) {
1637 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
1638 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
1639 + Integer.toHexString(mHistoryCur.states));
1640 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1641 }
1642 getUidStatsLocked(uid).noteStopSensor(sensor);
1643 }
1644
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001645 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001646
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001647 public void noteStartGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001648 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001649 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001650 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
1651 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001652 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001653 }
1654 mGpsNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001655 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001657
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001658 public void noteStopGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001659 mGpsNesting--;
1660 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001661 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001662 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
1663 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001664 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001665 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001666 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001667 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669 public void noteScreenOnLocked() {
1670 if (!mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001671 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001672 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
1673 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001674 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 mScreenOn = true;
1676 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001677 if (mScreenBrightnessBin >= 0) {
1678 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1679 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001680
1681 // Fake a wake lock, so we consider the device waked as long
1682 // as the screen is on.
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001683 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001684
1685 // Update discharge amounts.
1686 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001687 updateDischargeScreenLevelsLocked(false, true);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001689 }
1690 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001692 public void noteScreenOffLocked() {
1693 if (mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001694 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001695 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
1696 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001697 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001698 mScreenOn = false;
1699 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001700 if (mScreenBrightnessBin >= 0) {
1701 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1702 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001703
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001704 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001705
1706 // Update discharge amounts.
1707 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001708 updateDischargeScreenLevelsLocked(true, false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001709 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001710 }
1711 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001712
Dianne Hackborn617f8772009-03-31 15:04:46 -07001713 public void noteScreenBrightnessLocked(int brightness) {
1714 // Bin the brightness.
1715 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1716 if (bin < 0) bin = 0;
1717 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1718 if (mScreenBrightnessBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001719 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
1720 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001721 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
1722 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001723 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001724 if (mScreenOn) {
1725 if (mScreenBrightnessBin >= 0) {
1726 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1727 }
1728 mScreenBrightnessTimer[bin].startRunningLocked(this);
1729 }
1730 mScreenBrightnessBin = bin;
1731 }
1732 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001733
Christopher Tate4cee7252010-03-19 14:50:40 -07001734 public void noteInputEventAtomic() {
1735 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001736 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001737
Dianne Hackborn617f8772009-03-31 15:04:46 -07001738 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001739 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001740 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001742 public void notePhoneOnLocked() {
1743 if (!mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001744 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001745 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
1746 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001747 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001748 mPhoneOn = true;
1749 mPhoneOnTimer.startRunningLocked(this);
1750 }
1751 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001753 public void notePhoneOffLocked() {
1754 if (mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001755 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001756 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
1757 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001758 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001759 mPhoneOn = false;
1760 mPhoneOnTimer.stopRunningLocked(this);
1761 }
1762 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001763
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001764 void stopAllSignalStrengthTimersLocked(int except) {
Wink Saville52840902011-02-18 12:40:47 -08001765 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001766 if (i == except) {
1767 continue;
1768 }
1769 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1770 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
1771 }
1772 }
1773 }
1774
Dianne Hackborne4a59512010-12-07 11:08:07 -08001775 private int fixPhoneServiceState(int state, int signalBin) {
1776 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
1777 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1778 // to infer that we are scanning from other data.
1779 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08001780 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001781 state = ServiceState.STATE_IN_SERVICE;
1782 }
1783 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001784
Dianne Hackborne4a59512010-12-07 11:08:07 -08001785 return state;
1786 }
1787
1788 private void updateAllPhoneStateLocked(int state, int simState, int bin) {
1789 boolean scanning = false;
1790 boolean newHistory = false;
1791
1792 mPhoneServiceStateRaw = state;
1793 mPhoneSimStateRaw = simState;
1794 mPhoneSignalStrengthBinRaw = bin;
1795
1796 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
1797 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1798 // to infer that we are scanning from other data.
1799 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08001800 && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001801 state = ServiceState.STATE_IN_SERVICE;
1802 }
1803 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001804
1805 // If the phone is powered off, stop all timers.
1806 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001807 bin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001808
Dianne Hackborne4a59512010-12-07 11:08:07 -08001809 // If we are in service, make sure the correct signal string timer is running.
1810 } else if (state == ServiceState.STATE_IN_SERVICE) {
1811 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001812
1813 // If we're out of service, we are in the lowest signal strength
1814 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07001815 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001816 scanning = true;
Wink Saville52840902011-02-18 12:40:47 -08001817 bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001818 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001819 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001820 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001821 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
1822 + Integer.toHexString(mHistoryCur.states));
Amith Yamasanif37447b2009-10-08 18:28:01 -07001823 mPhoneSignalScanningTimer.startRunningLocked(this);
1824 }
1825 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001826
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001827 if (!scanning) {
1828 // If we are no longer scanning, then stop the scanning timer.
1829 if (mPhoneSignalScanningTimer.isRunningLocked()) {
1830 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
1831 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
1832 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001833 newHistory = true;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001834 mPhoneSignalScanningTimer.stopRunningLocked(this);
1835 }
1836 }
1837
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001838 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001839 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
1840 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08001841 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001842 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001843 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001844 mPhoneServiceState = state;
1845 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001846
1847 if (mPhoneSignalStrengthBin != bin) {
1848 if (mPhoneSignalStrengthBin >= 0) {
1849 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1850 }
1851 if (bin >= 0) {
1852 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1853 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1854 }
1855 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
1856 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
1857 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
1858 + Integer.toHexString(mHistoryCur.states));
1859 newHistory = true;
1860 } else {
1861 stopAllSignalStrengthTimersLocked(-1);
1862 }
1863 mPhoneSignalStrengthBin = bin;
1864 }
1865
1866 if (newHistory) {
1867 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1868 }
1869 }
1870
1871 /**
1872 * Telephony stack updates the phone state.
1873 * @param state phone state from ServiceState.getState()
1874 */
1875 public void notePhoneStateLocked(int state, int simState) {
1876 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001877 }
1878
Wink Savillee9b06d72009-05-18 21:47:50 -07001879 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001880 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08001881 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08001882 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001883 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001884
Dianne Hackborn627bba72009-03-24 22:32:56 -07001885 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1886 int bin = DATA_CONNECTION_NONE;
1887 if (hasData) {
1888 switch (dataType) {
1889 case TelephonyManager.NETWORK_TYPE_EDGE:
1890 bin = DATA_CONNECTION_EDGE;
1891 break;
1892 case TelephonyManager.NETWORK_TYPE_GPRS:
1893 bin = DATA_CONNECTION_GPRS;
1894 break;
1895 case TelephonyManager.NETWORK_TYPE_UMTS:
1896 bin = DATA_CONNECTION_UMTS;
1897 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001898 case TelephonyManager.NETWORK_TYPE_CDMA:
1899 bin = DATA_CONNECTION_CDMA;
1900 break;
1901 case TelephonyManager.NETWORK_TYPE_EVDO_0:
1902 bin = DATA_CONNECTION_EVDO_0;
1903 break;
1904 case TelephonyManager.NETWORK_TYPE_EVDO_A:
1905 bin = DATA_CONNECTION_EVDO_A;
1906 break;
1907 case TelephonyManager.NETWORK_TYPE_1xRTT:
1908 bin = DATA_CONNECTION_1xRTT;
1909 break;
1910 case TelephonyManager.NETWORK_TYPE_HSDPA:
1911 bin = DATA_CONNECTION_HSDPA;
1912 break;
1913 case TelephonyManager.NETWORK_TYPE_HSUPA:
1914 bin = DATA_CONNECTION_HSUPA;
1915 break;
1916 case TelephonyManager.NETWORK_TYPE_HSPA:
1917 bin = DATA_CONNECTION_HSPA;
1918 break;
1919 case TelephonyManager.NETWORK_TYPE_IDEN:
1920 bin = DATA_CONNECTION_IDEN;
1921 break;
1922 case TelephonyManager.NETWORK_TYPE_EVDO_B:
1923 bin = DATA_CONNECTION_EVDO_B;
1924 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07001925 case TelephonyManager.NETWORK_TYPE_LTE:
1926 bin = DATA_CONNECTION_LTE;
1927 break;
1928 case TelephonyManager.NETWORK_TYPE_EHRPD:
1929 bin = DATA_CONNECTION_EHRPD;
1930 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001931 default:
1932 bin = DATA_CONNECTION_OTHER;
1933 break;
1934 }
1935 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001936 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001937 if (mPhoneDataConnectionType != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001938 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
1939 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001940 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
1941 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001942 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07001943 if (mPhoneDataConnectionType >= 0) {
1944 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
1945 }
1946 mPhoneDataConnectionType = bin;
1947 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
1948 }
1949 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001950
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001951 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07001952 if (!mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001953 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001954 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
1955 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001956 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001957 mWifiOn = true;
1958 mWifiOnTimer.startRunningLocked(this);
1959 }
1960 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001961
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001962 public void noteWifiOffLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07001963 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001964 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001965 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
1966 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001967 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001968 mWifiOn = false;
1969 mWifiOnTimer.stopRunningLocked(this);
1970 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001971 if (mWifiOnUid >= 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001972 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001973 mWifiOnUid = -1;
1974 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001975 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001976
1977 public void noteAudioOnLocked(int uid) {
1978 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001979 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001980 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
1981 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001982 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001983 mAudioOn = true;
1984 mAudioOnTimer.startRunningLocked(this);
1985 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001986 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001987 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001988
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001989 public void noteAudioOffLocked(int uid) {
1990 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001991 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001992 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
1993 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001994 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001995 mAudioOn = false;
1996 mAudioOnTimer.stopRunningLocked(this);
1997 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001998 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001999 }
2000
2001 public void noteVideoOnLocked(int uid) {
2002 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002003 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002004 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
2005 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002006 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002007 mVideoOn = true;
2008 mVideoOnTimer.startRunningLocked(this);
2009 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002010 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002011 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002012
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002013 public void noteVideoOffLocked(int uid) {
2014 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002015 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002016 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
2017 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002018 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002019 mVideoOn = false;
2020 mVideoOnTimer.stopRunningLocked(this);
2021 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002022 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002023 }
2024
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002025 public void noteWifiRunningLocked(WorkSource ws) {
2026 if (!mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002027 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002028 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
2029 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002030 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002031 mGlobalWifiRunning = true;
2032 mGlobalWifiRunningTimer.startRunningLocked(this);
2033 int N = ws.size();
2034 for (int i=0; i<N; i++) {
2035 getUidStatsLocked(ws.get(i)).noteWifiRunningLocked();
2036 }
2037 } else {
2038 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002039 }
2040 }
2041
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002042 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
2043 if (mGlobalWifiRunning) {
2044 int N = oldWs.size();
2045 for (int i=0; i<N; i++) {
2046 getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked();
2047 }
2048 N = newWs.size();
2049 for (int i=0; i<N; i++) {
2050 getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked();
2051 }
2052 } else {
2053 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
2054 }
2055 }
2056
2057 public void noteWifiStoppedLocked(WorkSource ws) {
2058 if (mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002059 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002060 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
2061 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002062 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002063 mGlobalWifiRunning = false;
2064 mGlobalWifiRunningTimer.stopRunningLocked(this);
2065 int N = ws.size();
2066 for (int i=0; i<N; i++) {
2067 getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked();
2068 }
2069 } else {
2070 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002071 }
2072 }
2073
The Android Open Source Project10592532009-03-18 17:39:46 -07002074 public void noteBluetoothOnLocked() {
2075 if (!mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002076 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002077 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
2078 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002079 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002080 mBluetoothOn = true;
2081 mBluetoothOnTimer.startRunningLocked(this);
2082 }
2083 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002084
The Android Open Source Project10592532009-03-18 17:39:46 -07002085 public void noteBluetoothOffLocked() {
2086 if (mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002087 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002088 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
2089 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002090 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002091 mBluetoothOn = false;
2092 mBluetoothOnTimer.stopRunningLocked(this);
2093 }
2094 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002095
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002096 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002097
The Android Open Source Project10592532009-03-18 17:39:46 -07002098 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002099 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002100 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002101 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
2102 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002103 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002104 }
2105 mWifiFullLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002106 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002107 }
2108
2109 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002110 mWifiFullLockNesting--;
2111 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002112 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002113 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
2114 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002115 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002116 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002117 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002118 }
2119
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002120 int mWifiScanLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002121
The Android Open Source Project10592532009-03-18 17:39:46 -07002122 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002123 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002124 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002125 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: "
2126 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002127 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002128 }
2129 mWifiScanLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002130 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002131 }
2132
2133 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002134 mWifiScanLockNesting--;
2135 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002136 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002137 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: "
2138 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002139 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002140 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002141 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002142 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002143
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002144 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002145
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002146 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002147 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002148 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002149 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
2150 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002151 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002152 }
2153 mWifiMulticastNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002154 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002155 }
2156
2157 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002158 mWifiMulticastNesting--;
2159 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002160 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002161 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
2162 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002163 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002164 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002165 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002166 }
2167
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002168 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2169 int N = ws.size();
2170 for (int i=0; i<N; i++) {
2171 noteFullWifiLockAcquiredLocked(ws.get(i));
2172 }
2173 }
2174
2175 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
2176 int N = ws.size();
2177 for (int i=0; i<N; i++) {
2178 noteFullWifiLockReleasedLocked(ws.get(i));
2179 }
2180 }
2181
2182 public void noteScanWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2183 int N = ws.size();
2184 for (int i=0; i<N; i++) {
2185 noteScanWifiLockAcquiredLocked(ws.get(i));
2186 }
2187 }
2188
2189 public void noteScanWifiLockReleasedFromSourceLocked(WorkSource ws) {
2190 int N = ws.size();
2191 for (int i=0; i<N; i++) {
2192 noteScanWifiLockReleasedLocked(ws.get(i));
2193 }
2194 }
2195
2196 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
2197 int N = ws.size();
2198 for (int i=0; i<N; i++) {
2199 noteWifiMulticastEnabledLocked(ws.get(i));
2200 }
2201 }
2202
2203 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
2204 int N = ws.size();
2205 for (int i=0; i<N; i++) {
2206 noteWifiMulticastDisabledLocked(ws.get(i));
2207 }
2208 }
2209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002210 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002211 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002212 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002213
Dianne Hackborn617f8772009-03-31 15:04:46 -07002214 @Override public long getScreenBrightnessTime(int brightnessBin,
2215 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002216 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07002217 batteryRealtime, which);
2218 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002219
Dianne Hackborn617f8772009-03-31 15:04:46 -07002220 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002221 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002222 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002224 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002225 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002226 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002227
Dianne Hackborn627bba72009-03-24 22:32:56 -07002228 @Override public long getPhoneSignalStrengthTime(int strengthBin,
2229 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002230 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002231 batteryRealtime, which);
2232 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002233
2234 @Override public long getPhoneSignalScanningTime(
2235 long batteryRealtime, int which) {
2236 return mPhoneSignalScanningTimer.getTotalTimeLocked(
2237 batteryRealtime, which);
2238 }
2239
Dianne Hackborn617f8772009-03-31 15:04:46 -07002240 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002241 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002242 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002243
Dianne Hackborn627bba72009-03-24 22:32:56 -07002244 @Override public long getPhoneDataConnectionTime(int dataType,
2245 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002246 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002247 batteryRealtime, which);
2248 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002249
Dianne Hackborn617f8772009-03-31 15:04:46 -07002250 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002251 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002252 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002253
The Android Open Source Project10592532009-03-18 17:39:46 -07002254 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002255 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002256 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002257
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002258 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) {
2259 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002260 }
2261
The Android Open Source Project10592532009-03-18 17:39:46 -07002262 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002263 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002264 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 @Override public boolean getIsOnBattery() {
2267 return mOnBattery;
2268 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
2271 return mUidStats;
2272 }
2273
2274 /**
2275 * The statistics associated with a particular uid.
2276 */
2277 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002279 final int mUid;
2280 long mLoadedTcpBytesReceived;
2281 long mLoadedTcpBytesSent;
2282 long mCurrentTcpBytesReceived;
2283 long mCurrentTcpBytesSent;
2284 long mTcpBytesReceivedAtLastUnplug;
2285 long mTcpBytesSentAtLastUnplug;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002287 // These are not saved/restored when parcelling, since we want
2288 // to return from the parcel with a snapshot of the state.
2289 long mStartedTcpBytesReceived = -1;
2290 long mStartedTcpBytesSent = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002291
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002292 boolean mWifiRunning;
2293 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002294
The Android Open Source Project10592532009-03-18 17:39:46 -07002295 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002296 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002297
The Android Open Source Project10592532009-03-18 17:39:46 -07002298 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002299 StopwatchTimer mScanWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002300
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002301 boolean mWifiMulticastEnabled;
2302 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002303
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002304 boolean mAudioTurnedOn;
2305 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002306
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002307 boolean mVideoTurnedOn;
2308 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002309
Dianne Hackborn617f8772009-03-31 15:04:46 -07002310 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 /**
2313 * The statistics we have collected for this uid's wake locks.
2314 */
2315 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
2316
2317 /**
2318 * The statistics we have collected for this uid's sensor activations.
2319 */
2320 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
2321
2322 /**
2323 * The statistics we have collected for this uid's processes.
2324 */
2325 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
2326
2327 /**
2328 * The statistics we have collected for this uid's processes.
2329 */
2330 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002331
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002332 /**
2333 * The transient wake stats we have collected for this uid's pids.
2334 */
2335 final SparseArray<Pid> mPids = new SparseArray<Pid>();
2336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002337 public Uid(int uid) {
2338 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002339 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2340 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002341 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002342 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002343 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002344 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002345 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002346 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002347 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
2348 null, mUnpluggables);
2349 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
2350 null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 }
2352
2353 @Override
2354 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
2355 return mWakelockStats;
2356 }
2357
2358 @Override
2359 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
2360 return mSensorStats;
2361 }
2362
2363 @Override
2364 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
2365 return mProcessStats;
2366 }
2367
2368 @Override
2369 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
2370 return mPackageStats;
2371 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002372
2373 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 public int getUid() {
2375 return mUid;
2376 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002377
2378 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002379 public long getTcpBytesReceived(int which) {
2380 if (which == STATS_LAST) {
2381 return mLoadedTcpBytesReceived;
2382 } else {
2383 long current = computeCurrentTcpBytesReceived();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002384 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002385 current -= mTcpBytesReceivedAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002386 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002387 current += mLoadedTcpBytesReceived;
2388 }
2389 return current;
2390 }
2391 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 public long computeCurrentTcpBytesReceived() {
2394 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08002395 ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002397
2398 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 public long getTcpBytesSent(int which) {
2400 if (which == STATS_LAST) {
2401 return mLoadedTcpBytesSent;
2402 } else {
2403 long current = computeCurrentTcpBytesSent();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002404 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 current -= mTcpBytesSentAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002406 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 current += mLoadedTcpBytesSent;
2408 }
2409 return current;
2410 }
2411 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002412
The Android Open Source Project10592532009-03-18 17:39:46 -07002413 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002414 public void noteWifiRunningLocked() {
2415 if (!mWifiRunning) {
2416 mWifiRunning = true;
2417 if (mWifiRunningTimer == null) {
2418 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2419 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002420 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002421 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002422 }
2423 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002424
Dianne Hackborn617f8772009-03-31 15:04:46 -07002425 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002426 public void noteWifiStoppedLocked() {
2427 if (mWifiRunning) {
2428 mWifiRunning = false;
2429 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002430 }
2431 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002432
Dianne Hackborn617f8772009-03-31 15:04:46 -07002433 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002434 public void noteFullWifiLockAcquiredLocked() {
2435 if (!mFullWifiLockOut) {
2436 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002437 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002438 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002439 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002440 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002441 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2442 }
2443 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002444
The Android Open Source Project10592532009-03-18 17:39:46 -07002445 @Override
2446 public void noteFullWifiLockReleasedLocked() {
2447 if (mFullWifiLockOut) {
2448 mFullWifiLockOut = false;
2449 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2450 }
2451 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002452
The Android Open Source Project10592532009-03-18 17:39:46 -07002453 @Override
2454 public void noteScanWifiLockAcquiredLocked() {
2455 if (!mScanWifiLockOut) {
2456 mScanWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002457 if (mScanWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002458 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002459 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002460 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002461 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2462 }
2463 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002464
The Android Open Source Project10592532009-03-18 17:39:46 -07002465 @Override
2466 public void noteScanWifiLockReleasedLocked() {
2467 if (mScanWifiLockOut) {
2468 mScanWifiLockOut = false;
2469 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2470 }
2471 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002472
2473 @Override
2474 public void noteWifiMulticastEnabledLocked() {
2475 if (!mWifiMulticastEnabled) {
2476 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002477 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002478 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002479 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002480 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002481 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
2482 }
2483 }
2484
2485 @Override
2486 public void noteWifiMulticastDisabledLocked() {
2487 if (mWifiMulticastEnabled) {
2488 mWifiMulticastEnabled = false;
2489 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
2490 }
2491 }
2492
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002493 @Override
2494 public void noteAudioTurnedOnLocked() {
2495 if (!mAudioTurnedOn) {
2496 mAudioTurnedOn = true;
2497 if (mAudioTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002498 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002499 null, mUnpluggables);
2500 }
2501 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2502 }
2503 }
2504
2505 @Override
2506 public void noteAudioTurnedOffLocked() {
2507 if (mAudioTurnedOn) {
2508 mAudioTurnedOn = false;
2509 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2510 }
2511 }
2512
2513 @Override
2514 public void noteVideoTurnedOnLocked() {
2515 if (!mVideoTurnedOn) {
2516 mVideoTurnedOn = true;
2517 if (mVideoTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002518 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002519 null, mUnpluggables);
2520 }
2521 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2522 }
2523 }
2524
2525 @Override
2526 public void noteVideoTurnedOffLocked() {
2527 if (mVideoTurnedOn) {
2528 mVideoTurnedOn = false;
2529 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2530 }
2531 }
2532
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002533 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002534 public long getWifiRunningTime(long batteryRealtime, int which) {
2535 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002536 return 0;
2537 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002538 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002539 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002540
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002541 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002542 public long getFullWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002543 if (mFullWifiLockTimer == null) {
2544 return 0;
2545 }
Evan Millarc64edde2009-04-18 12:26:32 -07002546 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002547 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002548
2549 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002550 public long getScanWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002551 if (mScanWifiLockTimer == null) {
2552 return 0;
2553 }
Evan Millarc64edde2009-04-18 12:26:32 -07002554 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002555 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002556
2557 @Override
2558 public long getWifiMulticastTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002559 if (mWifiMulticastTimer == null) {
2560 return 0;
2561 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002562 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
2563 which);
2564 }
2565
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002566 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002567 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
2568 if (mAudioTurnedOnTimer == null) {
2569 return 0;
2570 }
2571 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2572 }
2573
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002574 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002575 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
2576 if (mVideoTurnedOnTimer == null) {
2577 return 0;
2578 }
2579 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2580 }
2581
Dianne Hackborn617f8772009-03-31 15:04:46 -07002582 @Override
2583 public void noteUserActivityLocked(int type) {
2584 if (mUserActivityCounters == null) {
2585 initUserActivityLocked();
2586 }
2587 if (type < 0) type = 0;
2588 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
Christopher Tate4cee7252010-03-19 14:50:40 -07002589 mUserActivityCounters[type].stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002590 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002591
Dianne Hackborn617f8772009-03-31 15:04:46 -07002592 @Override
2593 public boolean hasUserActivity() {
2594 return mUserActivityCounters != null;
2595 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002596
Dianne Hackborn617f8772009-03-31 15:04:46 -07002597 @Override
2598 public int getUserActivityCount(int type, int which) {
2599 if (mUserActivityCounters == null) {
2600 return 0;
2601 }
Evan Millarc64edde2009-04-18 12:26:32 -07002602 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002603 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002604
Dianne Hackborn617f8772009-03-31 15:04:46 -07002605 void initUserActivityLocked() {
2606 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2607 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2608 mUserActivityCounters[i] = new Counter(mUnpluggables);
2609 }
2610 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 public long computeCurrentTcpBytesSent() {
2613 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08002614 ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002616
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002617 /**
2618 * Clear all stats for this uid. Returns true if the uid is completely
2619 * inactive so can be dropped.
2620 */
2621 boolean reset() {
2622 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002623
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002624 if (mWifiRunningTimer != null) {
2625 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false);
2626 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002627 }
2628 if (mFullWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002629 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002630 active |= mFullWifiLockOut;
2631 }
2632 if (mScanWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002633 active |= !mScanWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002634 active |= mScanWifiLockOut;
2635 }
2636 if (mWifiMulticastTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002637 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002638 active |= mWifiMulticastEnabled;
2639 }
2640 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002641 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002642 active |= mAudioTurnedOn;
2643 }
2644 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002645 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002646 active |= mVideoTurnedOn;
2647 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002648
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002649 mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0;
2650 mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002651
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002652 if (mUserActivityCounters != null) {
2653 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2654 mUserActivityCounters[i].reset(false);
2655 }
2656 }
2657
2658 if (mWakelockStats.size() > 0) {
2659 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
2660 while (it.hasNext()) {
2661 Map.Entry<String, Wakelock> wakelockEntry = it.next();
2662 Wakelock wl = wakelockEntry.getValue();
2663 if (wl.reset()) {
2664 it.remove();
2665 } else {
2666 active = true;
2667 }
2668 }
2669 }
2670 if (mSensorStats.size() > 0) {
2671 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
2672 while (it.hasNext()) {
2673 Map.Entry<Integer, Sensor> sensorEntry = it.next();
2674 Sensor s = sensorEntry.getValue();
2675 if (s.reset()) {
2676 it.remove();
2677 } else {
2678 active = true;
2679 }
2680 }
2681 }
2682 if (mProcessStats.size() > 0) {
2683 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
2684 while (it.hasNext()) {
2685 Map.Entry<String, Proc> procEntry = it.next();
2686 procEntry.getValue().detach();
2687 }
2688 mProcessStats.clear();
2689 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002690 if (mPids.size() > 0) {
2691 for (int i=0; !active && i<mPids.size(); i++) {
2692 Pid pid = mPids.valueAt(i);
2693 if (pid.mWakeStart != 0) {
2694 active = true;
2695 }
2696 }
2697 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002698 if (mPackageStats.size() > 0) {
2699 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
2700 while (it.hasNext()) {
2701 Map.Entry<String, Pkg> pkgEntry = it.next();
2702 Pkg p = pkgEntry.getValue();
2703 p.detach();
2704 if (p.mServiceStats.size() > 0) {
2705 Iterator<Map.Entry<String, Pkg.Serv>> it2
2706 = p.mServiceStats.entrySet().iterator();
2707 while (it2.hasNext()) {
2708 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
2709 servEntry.getValue().detach();
2710 }
2711 }
2712 }
2713 mPackageStats.clear();
2714 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002715
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002716 mPids.clear();
2717
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002718 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002719 if (mWifiRunningTimer != null) {
2720 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002721 }
2722 if (mFullWifiLockTimer != null) {
2723 mFullWifiLockTimer.detach();
2724 }
2725 if (mScanWifiLockTimer != null) {
2726 mScanWifiLockTimer.detach();
2727 }
2728 if (mWifiMulticastTimer != null) {
2729 mWifiMulticastTimer.detach();
2730 }
2731 if (mAudioTurnedOnTimer != null) {
2732 mAudioTurnedOnTimer.detach();
2733 }
2734 if (mVideoTurnedOnTimer != null) {
2735 mVideoTurnedOnTimer.detach();
2736 }
2737 if (mUserActivityCounters != null) {
2738 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2739 mUserActivityCounters[i].detach();
2740 }
2741 }
2742 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002743
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002744 return !active;
2745 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002747 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2748 out.writeInt(mWakelockStats.size());
2749 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
2750 out.writeString(wakelockEntry.getKey());
2751 Uid.Wakelock wakelock = wakelockEntry.getValue();
2752 wakelock.writeToParcelLocked(out, batteryRealtime);
2753 }
2754
2755 out.writeInt(mSensorStats.size());
2756 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
2757 out.writeInt(sensorEntry.getKey());
2758 Uid.Sensor sensor = sensorEntry.getValue();
2759 sensor.writeToParcelLocked(out, batteryRealtime);
2760 }
2761
2762 out.writeInt(mProcessStats.size());
2763 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
2764 out.writeString(procEntry.getKey());
2765 Uid.Proc proc = procEntry.getValue();
2766 proc.writeToParcelLocked(out);
2767 }
2768
2769 out.writeInt(mPackageStats.size());
2770 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
2771 out.writeString(pkgEntry.getKey());
2772 Uid.Pkg pkg = pkgEntry.getValue();
2773 pkg.writeToParcelLocked(out);
2774 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002776 out.writeLong(mLoadedTcpBytesReceived);
2777 out.writeLong(mLoadedTcpBytesSent);
2778 out.writeLong(computeCurrentTcpBytesReceived());
2779 out.writeLong(computeCurrentTcpBytesSent());
2780 out.writeLong(mTcpBytesReceivedAtLastUnplug);
2781 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002782 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002783 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002784 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002785 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002786 out.writeInt(0);
2787 }
2788 if (mFullWifiLockTimer != null) {
2789 out.writeInt(1);
2790 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
2791 } else {
2792 out.writeInt(0);
2793 }
2794 if (mScanWifiLockTimer != null) {
2795 out.writeInt(1);
2796 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
2797 } else {
2798 out.writeInt(0);
2799 }
2800 if (mWifiMulticastTimer != null) {
2801 out.writeInt(1);
2802 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
2803 } else {
2804 out.writeInt(0);
2805 }
2806 if (mAudioTurnedOnTimer != null) {
2807 out.writeInt(1);
2808 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
2809 } else {
2810 out.writeInt(0);
2811 }
2812 if (mVideoTurnedOnTimer != null) {
2813 out.writeInt(1);
2814 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
2815 } else {
2816 out.writeInt(0);
2817 }
2818 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002819 out.writeInt(1);
2820 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2821 mUserActivityCounters[i].writeToParcel(out);
2822 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002823 } else {
2824 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 }
2827
2828 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2829 int numWakelocks = in.readInt();
2830 mWakelockStats.clear();
2831 for (int j = 0; j < numWakelocks; j++) {
2832 String wakelockName = in.readString();
2833 Uid.Wakelock wakelock = new Wakelock();
2834 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002835 if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) {
2836 // We will just drop some random set of wakelocks if
2837 // the previous run of the system was an older version
2838 // that didn't impose a limit.
2839 mWakelockStats.put(wakelockName, wakelock);
2840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002841 }
2842
2843 int numSensors = in.readInt();
2844 mSensorStats.clear();
2845 for (int k = 0; k < numSensors; k++) {
2846 int sensorNumber = in.readInt();
2847 Uid.Sensor sensor = new Sensor(sensorNumber);
2848 sensor.readFromParcelLocked(mUnpluggables, in);
2849 mSensorStats.put(sensorNumber, sensor);
2850 }
2851
2852 int numProcs = in.readInt();
2853 mProcessStats.clear();
2854 for (int k = 0; k < numProcs; k++) {
2855 String processName = in.readString();
2856 Uid.Proc proc = new Proc();
2857 proc.readFromParcelLocked(in);
2858 mProcessStats.put(processName, proc);
2859 }
2860
2861 int numPkgs = in.readInt();
2862 mPackageStats.clear();
2863 for (int l = 0; l < numPkgs; l++) {
2864 String packageName = in.readString();
2865 Uid.Pkg pkg = new Pkg();
2866 pkg.readFromParcelLocked(in);
2867 mPackageStats.put(packageName, pkg);
2868 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002870 mLoadedTcpBytesReceived = in.readLong();
2871 mLoadedTcpBytesSent = in.readLong();
2872 mCurrentTcpBytesReceived = in.readLong();
2873 mCurrentTcpBytesSent = in.readLong();
2874 mTcpBytesReceivedAtLastUnplug = in.readLong();
2875 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002876 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002877 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002878 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2879 mWifiRunningTimers, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002880 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002881 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002882 }
2883 mFullWifiLockOut = false;
2884 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002885 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002886 mFullWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002887 } else {
2888 mFullWifiLockTimer = null;
2889 }
2890 mScanWifiLockOut = false;
2891 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002892 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002893 mScanWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002894 } else {
2895 mScanWifiLockTimer = null;
2896 }
2897 mWifiMulticastEnabled = false;
2898 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002899 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002900 mWifiMulticastTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002901 } else {
2902 mWifiMulticastTimer = null;
2903 }
2904 mAudioTurnedOn = false;
2905 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002906 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002907 null, mUnpluggables, in);
2908 } else {
2909 mAudioTurnedOnTimer = null;
2910 }
2911 mVideoTurnedOn = false;
2912 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002913 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002914 null, mUnpluggables, in);
2915 } else {
2916 mVideoTurnedOnTimer = null;
2917 }
2918 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002919 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2920 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2921 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
2922 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002923 } else {
2924 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07002925 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002926 }
2927
2928 /**
2929 * The statistics associated with a particular wake lock.
2930 */
2931 public final class Wakelock extends BatteryStats.Uid.Wakelock {
2932 /**
2933 * How long (in ms) this uid has been keeping the device partially awake.
2934 */
Evan Millarc64edde2009-04-18 12:26:32 -07002935 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936
2937 /**
2938 * How long (in ms) this uid has been keeping the device fully awake.
2939 */
Evan Millarc64edde2009-04-18 12:26:32 -07002940 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941
2942 /**
2943 * How long (in ms) this uid has had a window keeping the device awake.
2944 */
Evan Millarc64edde2009-04-18 12:26:32 -07002945 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002946
2947 /**
2948 * Reads a possibly null Timer from a Parcel. The timer is associated with the
2949 * proper timer pool from the given BatteryStatsImpl object.
2950 *
2951 * @param in the Parcel to be read from.
2952 * return a new Timer, or null.
2953 */
Evan Millarc64edde2009-04-18 12:26:32 -07002954 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 ArrayList<Unpluggable> unpluggables, Parcel in) {
2956 if (in.readInt() == 0) {
2957 return null;
2958 }
2959
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002960 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002961 }
2962
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002963 boolean reset() {
2964 boolean wlactive = false;
2965 if (mTimerFull != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002966 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002967 }
2968 if (mTimerPartial != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002969 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002970 }
2971 if (mTimerWindow != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002972 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002973 }
2974 if (!wlactive) {
2975 if (mTimerFull != null) {
2976 mTimerFull.detach();
2977 mTimerFull = null;
2978 }
2979 if (mTimerPartial != null) {
2980 mTimerPartial.detach();
2981 mTimerPartial = null;
2982 }
2983 if (mTimerWindow != null) {
2984 mTimerWindow.detach();
2985 mTimerWindow = null;
2986 }
2987 }
2988 return !wlactive;
2989 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002991 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2992 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
2993 mPartialTimers, unpluggables, in);
2994 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
2995 mFullTimers, unpluggables, in);
2996 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
2997 mWindowTimers, unpluggables, in);
2998 }
2999
3000 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3001 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
3002 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
3003 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
3004 }
3005
3006 @Override
3007 public Timer getWakeTime(int type) {
3008 switch (type) {
3009 case WAKE_TYPE_FULL: return mTimerFull;
3010 case WAKE_TYPE_PARTIAL: return mTimerPartial;
3011 case WAKE_TYPE_WINDOW: return mTimerWindow;
3012 default: throw new IllegalArgumentException("type = " + type);
3013 }
3014 }
3015 }
3016
3017 public final class Sensor extends BatteryStats.Uid.Sensor {
3018 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07003019 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003021 public Sensor(int handle) {
3022 mHandle = handle;
3023 }
3024
Evan Millarc64edde2009-04-18 12:26:32 -07003025 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 Parcel in) {
3027 if (in.readInt() == 0) {
3028 return null;
3029 }
3030
Evan Millarc64edde2009-04-18 12:26:32 -07003031 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003033 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003034 mSensorTimers.put(mHandle, pool);
3035 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003036 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003037 }
3038
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003039 boolean reset() {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003040 if (mTimer.reset(BatteryStatsImpl.this, true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003041 mTimer = null;
3042 return true;
3043 }
3044 return false;
3045 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3048 mTimer = readTimerFromParcel(unpluggables, in);
3049 }
3050
3051 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3052 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
3053 }
3054
3055 @Override
3056 public Timer getSensorTime() {
3057 return mTimer;
3058 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003059
3060 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 public int getHandle() {
3062 return mHandle;
3063 }
3064 }
3065
3066 /**
3067 * The statistics associated with a particular process.
3068 */
3069 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
3070 /**
3071 * Total time (in 1/100 sec) spent executing in user code.
3072 */
3073 long mUserTime;
3074
3075 /**
3076 * Total time (in 1/100 sec) spent executing in kernel code.
3077 */
3078 long mSystemTime;
3079
3080 /**
3081 * Number of times the process has been started.
3082 */
3083 int mStarts;
3084
3085 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003086 * Amount of time the process was running in the foreground.
3087 */
3088 long mForegroundTime;
3089
3090 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003091 * The amount of user time loaded from a previous save.
3092 */
3093 long mLoadedUserTime;
3094
3095 /**
3096 * The amount of system time loaded from a previous save.
3097 */
3098 long mLoadedSystemTime;
3099
3100 /**
3101 * The number of times the process has started from a previous save.
3102 */
3103 int mLoadedStarts;
3104
3105 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003106 * The amount of foreground time loaded from a previous save.
3107 */
3108 long mLoadedForegroundTime;
3109
3110 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003111 * The amount of user time loaded from the previous run.
3112 */
3113 long mLastUserTime;
3114
3115 /**
3116 * The amount of system time loaded from the previous run.
3117 */
3118 long mLastSystemTime;
3119
3120 /**
3121 * The number of times the process has started from the previous run.
3122 */
3123 int mLastStarts;
3124
3125 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003126 * The amount of foreground time loaded from the previous run
3127 */
3128 long mLastForegroundTime;
3129
3130 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003131 * The amount of user time when last unplugged.
3132 */
3133 long mUnpluggedUserTime;
3134
3135 /**
3136 * The amount of system time when last unplugged.
3137 */
3138 long mUnpluggedSystemTime;
3139
3140 /**
3141 * The number of times the process has started before unplugged.
3142 */
3143 int mUnpluggedStarts;
3144
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003145 /**
3146 * The amount of foreground time since unplugged.
3147 */
3148 long mUnpluggedForegroundTime;
3149
Amith Yamasanie43530a2009-08-21 13:11:37 -07003150 SamplingCounter[] mSpeedBins;
3151
Dianne Hackborn287952c2010-09-22 22:34:31 -07003152 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003154 Proc() {
3155 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003156 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003159 public void unplug(long batteryUptime, long batteryRealtime) {
3160 mUnpluggedUserTime = mUserTime;
3161 mUnpluggedSystemTime = mSystemTime;
3162 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003163 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003164 }
3165
3166 public void plug(long batteryUptime, long batteryRealtime) {
3167 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003168
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003169 void detach() {
3170 mUnpluggables.remove(this);
3171 for (int i = 0; i < mSpeedBins.length; i++) {
3172 SamplingCounter c = mSpeedBins[i];
3173 if (c != null) {
3174 mUnpluggables.remove(c);
3175 mSpeedBins[i] = null;
3176 }
3177 }
3178 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003179
Dianne Hackborn287952c2010-09-22 22:34:31 -07003180 public int countExcessivePowers() {
3181 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003182 }
3183
Dianne Hackborn287952c2010-09-22 22:34:31 -07003184 public ExcessivePower getExcessivePower(int i) {
3185 if (mExcessivePower != null) {
3186 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003187 }
3188 return null;
3189 }
3190
3191 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003192 if (mExcessivePower == null) {
3193 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003194 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07003195 ExcessivePower ew = new ExcessivePower();
3196 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003197 ew.overTime = overTime;
3198 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07003199 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003200 }
3201
Dianne Hackborn287952c2010-09-22 22:34:31 -07003202 public void addExcessiveCpu(long overTime, long usedTime) {
3203 if (mExcessivePower == null) {
3204 mExcessivePower = new ArrayList<ExcessivePower>();
3205 }
3206 ExcessivePower ew = new ExcessivePower();
3207 ew.type = ExcessivePower.TYPE_CPU;
3208 ew.overTime = overTime;
3209 ew.usedTime = usedTime;
3210 mExcessivePower.add(ew);
3211 }
3212
3213 void writeExcessivePowerToParcelLocked(Parcel out) {
3214 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003215 out.writeInt(0);
3216 return;
3217 }
3218
Dianne Hackborn287952c2010-09-22 22:34:31 -07003219 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003220 out.writeInt(N);
3221 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003222 ExcessivePower ew = mExcessivePower.get(i);
3223 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003224 out.writeLong(ew.overTime);
3225 out.writeLong(ew.usedTime);
3226 }
3227 }
3228
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003229 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003230 final int N = in.readInt();
3231 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003232 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003233 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003234 }
3235
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003236 if (N > 10000) {
3237 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
3238 return false;
3239 }
3240
Dianne Hackborn287952c2010-09-22 22:34:31 -07003241 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003242 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003243 ExcessivePower ew = new ExcessivePower();
3244 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003245 ew.overTime = in.readLong();
3246 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07003247 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003248 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003249 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003250 }
3251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003252 void writeToParcelLocked(Parcel out) {
3253 out.writeLong(mUserTime);
3254 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003255 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003256 out.writeInt(mStarts);
3257 out.writeLong(mLoadedUserTime);
3258 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003259 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003260 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003261 out.writeLong(mUnpluggedUserTime);
3262 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003263 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003265
3266 out.writeInt(mSpeedBins.length);
3267 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003268 SamplingCounter c = mSpeedBins[i];
3269 if (c != null) {
3270 out.writeInt(1);
3271 c.writeToParcel(out);
3272 } else {
3273 out.writeInt(0);
3274 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003275 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003276
Dianne Hackborn287952c2010-09-22 22:34:31 -07003277 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003278 }
3279
3280 void readFromParcelLocked(Parcel in) {
3281 mUserTime = in.readLong();
3282 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003283 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003284 mStarts = in.readInt();
3285 mLoadedUserTime = in.readLong();
3286 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003287 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003288 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003289 mLastUserTime = 0;
3290 mLastSystemTime = 0;
3291 mLastForegroundTime = 0;
3292 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003293 mUnpluggedUserTime = in.readLong();
3294 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003295 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003296 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07003297
3298 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003299 int steps = getCpuSpeedSteps();
3300 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07003301 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003302 if (in.readInt() != 0) {
3303 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
3304 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003305 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003306
Dianne Hackborn287952c2010-09-22 22:34:31 -07003307 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 }
3309
3310 public BatteryStatsImpl getBatteryStats() {
3311 return BatteryStatsImpl.this;
3312 }
3313
3314 public void addCpuTimeLocked(int utime, int stime) {
3315 mUserTime += utime;
3316 mSystemTime += stime;
3317 }
3318
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003319 public void addForegroundTimeLocked(long ttime) {
3320 mForegroundTime += ttime;
3321 }
3322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003323 public void incStartsLocked() {
3324 mStarts++;
3325 }
3326
3327 @Override
3328 public long getUserTime(int which) {
3329 long val;
3330 if (which == STATS_LAST) {
3331 val = mLastUserTime;
3332 } else {
3333 val = mUserTime;
3334 if (which == STATS_CURRENT) {
3335 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003336 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003337 val -= mUnpluggedUserTime;
3338 }
3339 }
3340 return val;
3341 }
3342
3343 @Override
3344 public long getSystemTime(int which) {
3345 long val;
3346 if (which == STATS_LAST) {
3347 val = mLastSystemTime;
3348 } else {
3349 val = mSystemTime;
3350 if (which == STATS_CURRENT) {
3351 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003352 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 val -= mUnpluggedSystemTime;
3354 }
3355 }
3356 return val;
3357 }
3358
3359 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003360 public long getForegroundTime(int which) {
3361 long val;
3362 if (which == STATS_LAST) {
3363 val = mLastForegroundTime;
3364 } else {
3365 val = mForegroundTime;
3366 if (which == STATS_CURRENT) {
3367 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003368 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003369 val -= mUnpluggedForegroundTime;
3370 }
3371 }
3372 return val;
3373 }
3374
3375 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003376 public int getStarts(int which) {
3377 int val;
3378 if (which == STATS_LAST) {
3379 val = mLastStarts;
3380 } else {
3381 val = mStarts;
3382 if (which == STATS_CURRENT) {
3383 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003384 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003385 val -= mUnpluggedStarts;
3386 }
3387 }
3388 return val;
3389 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003390
3391 /* Called by ActivityManagerService when CPU times are updated. */
3392 public void addSpeedStepTimes(long[] values) {
3393 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003394 long amt = values[i];
3395 if (amt != 0) {
3396 SamplingCounter c = mSpeedBins[i];
3397 if (c == null) {
3398 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
3399 }
3400 c.addCountAtomic(values[i]);
3401 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003402 }
3403 }
3404
3405 @Override
3406 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
3407 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003408 SamplingCounter c = mSpeedBins[speedStep];
3409 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07003410 } else {
3411 return 0;
3412 }
3413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003414 }
3415
3416 /**
3417 * The statistics associated with a particular package.
3418 */
3419 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
3420 /**
3421 * Number of times this package has done something that could wake up the
3422 * device from sleep.
3423 */
3424 int mWakeups;
3425
3426 /**
3427 * Number of things that could wake up the device loaded from a
3428 * previous save.
3429 */
3430 int mLoadedWakeups;
3431
3432 /**
3433 * Number of things that could wake up the device as of the
3434 * last run.
3435 */
3436 int mLastWakeups;
3437
3438 /**
3439 * Number of things that could wake up the device as of the
3440 * last run.
3441 */
3442 int mUnpluggedWakeups;
3443
3444 /**
3445 * The statics we have collected for this package's services.
3446 */
3447 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
3448
3449 Pkg() {
3450 mUnpluggables.add(this);
3451 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003453 public void unplug(long batteryUptime, long batteryRealtime) {
3454 mUnpluggedWakeups = mWakeups;
3455 }
3456
3457 public void plug(long batteryUptime, long batteryRealtime) {
3458 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003459
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003460 void detach() {
3461 mUnpluggables.remove(this);
3462 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003464 void readFromParcelLocked(Parcel in) {
3465 mWakeups = in.readInt();
3466 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003467 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003468 mUnpluggedWakeups = in.readInt();
3469
3470 int numServs = in.readInt();
3471 mServiceStats.clear();
3472 for (int m = 0; m < numServs; m++) {
3473 String serviceName = in.readString();
3474 Uid.Pkg.Serv serv = new Serv();
3475 mServiceStats.put(serviceName, serv);
3476
3477 serv.readFromParcelLocked(in);
3478 }
3479 }
3480
3481 void writeToParcelLocked(Parcel out) {
3482 out.writeInt(mWakeups);
3483 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003484 out.writeInt(mUnpluggedWakeups);
3485
3486 out.writeInt(mServiceStats.size());
3487 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
3488 out.writeString(servEntry.getKey());
3489 Uid.Pkg.Serv serv = servEntry.getValue();
3490
3491 serv.writeToParcelLocked(out);
3492 }
3493 }
3494
3495 @Override
3496 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
3497 return mServiceStats;
3498 }
3499
3500 @Override
3501 public int getWakeups(int which) {
3502 int val;
3503 if (which == STATS_LAST) {
3504 val = mLastWakeups;
3505 } else {
3506 val = mWakeups;
3507 if (which == STATS_CURRENT) {
3508 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003509 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003510 val -= mUnpluggedWakeups;
3511 }
3512 }
3513
3514 return val;
3515 }
3516
3517 /**
3518 * The statistics associated with a particular service.
3519 */
3520 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
3521 /**
3522 * Total time (ms in battery uptime) the service has been left started.
3523 */
3524 long mStartTime;
3525
3526 /**
3527 * If service has been started and not yet stopped, this is
3528 * when it was started.
3529 */
3530 long mRunningSince;
3531
3532 /**
3533 * True if we are currently running.
3534 */
3535 boolean mRunning;
3536
3537 /**
3538 * Total number of times startService() has been called.
3539 */
3540 int mStarts;
3541
3542 /**
3543 * Total time (ms in battery uptime) the service has been left launched.
3544 */
3545 long mLaunchedTime;
3546
3547 /**
3548 * If service has been launched and not yet exited, this is
3549 * when it was launched (ms in battery uptime).
3550 */
3551 long mLaunchedSince;
3552
3553 /**
3554 * True if we are currently launched.
3555 */
3556 boolean mLaunched;
3557
3558 /**
3559 * Total number times the service has been launched.
3560 */
3561 int mLaunches;
3562
3563 /**
3564 * The amount of time spent started loaded from a previous save
3565 * (ms in battery uptime).
3566 */
3567 long mLoadedStartTime;
3568
3569 /**
3570 * The number of starts loaded from a previous save.
3571 */
3572 int mLoadedStarts;
3573
3574 /**
3575 * The number of launches loaded from a previous save.
3576 */
3577 int mLoadedLaunches;
3578
3579 /**
3580 * The amount of time spent started as of the last run (ms
3581 * in battery uptime).
3582 */
3583 long mLastStartTime;
3584
3585 /**
3586 * The number of starts as of the last run.
3587 */
3588 int mLastStarts;
3589
3590 /**
3591 * The number of launches as of the last run.
3592 */
3593 int mLastLaunches;
3594
3595 /**
3596 * The amount of time spent started when last unplugged (ms
3597 * in battery uptime).
3598 */
3599 long mUnpluggedStartTime;
3600
3601 /**
3602 * The number of starts when last unplugged.
3603 */
3604 int mUnpluggedStarts;
3605
3606 /**
3607 * The number of launches when last unplugged.
3608 */
3609 int mUnpluggedLaunches;
3610
3611 Serv() {
3612 mUnpluggables.add(this);
3613 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 public void unplug(long batteryUptime, long batteryRealtime) {
3616 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
3617 mUnpluggedStarts = mStarts;
3618 mUnpluggedLaunches = mLaunches;
3619 }
3620
3621 public void plug(long batteryUptime, long batteryRealtime) {
3622 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003623
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003624 void detach() {
3625 mUnpluggables.remove(this);
3626 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 void readFromParcelLocked(Parcel in) {
3629 mStartTime = in.readLong();
3630 mRunningSince = in.readLong();
3631 mRunning = in.readInt() != 0;
3632 mStarts = in.readInt();
3633 mLaunchedTime = in.readLong();
3634 mLaunchedSince = in.readLong();
3635 mLaunched = in.readInt() != 0;
3636 mLaunches = in.readInt();
3637 mLoadedStartTime = in.readLong();
3638 mLoadedStarts = in.readInt();
3639 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003640 mLastStartTime = 0;
3641 mLastStarts = 0;
3642 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003643 mUnpluggedStartTime = in.readLong();
3644 mUnpluggedStarts = in.readInt();
3645 mUnpluggedLaunches = in.readInt();
3646 }
3647
3648 void writeToParcelLocked(Parcel out) {
3649 out.writeLong(mStartTime);
3650 out.writeLong(mRunningSince);
3651 out.writeInt(mRunning ? 1 : 0);
3652 out.writeInt(mStarts);
3653 out.writeLong(mLaunchedTime);
3654 out.writeLong(mLaunchedSince);
3655 out.writeInt(mLaunched ? 1 : 0);
3656 out.writeInt(mLaunches);
3657 out.writeLong(mLoadedStartTime);
3658 out.writeInt(mLoadedStarts);
3659 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 out.writeLong(mUnpluggedStartTime);
3661 out.writeInt(mUnpluggedStarts);
3662 out.writeInt(mUnpluggedLaunches);
3663 }
3664
3665 long getLaunchTimeToNowLocked(long batteryUptime) {
3666 if (!mLaunched) return mLaunchedTime;
3667 return mLaunchedTime + batteryUptime - mLaunchedSince;
3668 }
3669
3670 long getStartTimeToNowLocked(long batteryUptime) {
3671 if (!mRunning) return mStartTime;
3672 return mStartTime + batteryUptime - mRunningSince;
3673 }
3674
3675 public void startLaunchedLocked() {
3676 if (!mLaunched) {
3677 mLaunches++;
3678 mLaunchedSince = getBatteryUptimeLocked();
3679 mLaunched = true;
3680 }
3681 }
3682
3683 public void stopLaunchedLocked() {
3684 if (mLaunched) {
3685 long time = getBatteryUptimeLocked() - mLaunchedSince;
3686 if (time > 0) {
3687 mLaunchedTime += time;
3688 } else {
3689 mLaunches--;
3690 }
3691 mLaunched = false;
3692 }
3693 }
3694
3695 public void startRunningLocked() {
3696 if (!mRunning) {
3697 mStarts++;
3698 mRunningSince = getBatteryUptimeLocked();
3699 mRunning = true;
3700 }
3701 }
3702
3703 public void stopRunningLocked() {
3704 if (mRunning) {
3705 long time = getBatteryUptimeLocked() - mRunningSince;
3706 if (time > 0) {
3707 mStartTime += time;
3708 } else {
3709 mStarts--;
3710 }
3711 mRunning = false;
3712 }
3713 }
3714
3715 public BatteryStatsImpl getBatteryStats() {
3716 return BatteryStatsImpl.this;
3717 }
3718
3719 @Override
3720 public int getLaunches(int which) {
3721 int val;
3722
3723 if (which == STATS_LAST) {
3724 val = mLastLaunches;
3725 } else {
3726 val = mLaunches;
3727 if (which == STATS_CURRENT) {
3728 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003729 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003730 val -= mUnpluggedLaunches;
3731 }
3732 }
3733
3734 return val;
3735 }
3736
3737 @Override
3738 public long getStartTime(long now, int which) {
3739 long val;
3740 if (which == STATS_LAST) {
3741 val = mLastStartTime;
3742 } else {
3743 val = getStartTimeToNowLocked(now);
3744 if (which == STATS_CURRENT) {
3745 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003746 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003747 val -= mUnpluggedStartTime;
3748 }
3749 }
3750
3751 return val;
3752 }
3753
3754 @Override
3755 public int getStarts(int which) {
3756 int val;
3757 if (which == STATS_LAST) {
3758 val = mLastStarts;
3759 } else {
3760 val = mStarts;
3761 if (which == STATS_CURRENT) {
3762 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003763 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003764 val -= mUnpluggedStarts;
3765 }
3766 }
3767
3768 return val;
3769 }
3770 }
3771
3772 public BatteryStatsImpl getBatteryStats() {
3773 return BatteryStatsImpl.this;
3774 }
3775
3776 public void incWakeupsLocked() {
3777 mWakeups++;
3778 }
3779
3780 final Serv newServiceStatsLocked() {
3781 return new Serv();
3782 }
3783 }
3784
3785 /**
3786 * Retrieve the statistics object for a particular process, creating
3787 * if needed.
3788 */
3789 public Proc getProcessStatsLocked(String name) {
3790 Proc ps = mProcessStats.get(name);
3791 if (ps == null) {
3792 ps = new Proc();
3793 mProcessStats.put(name, ps);
3794 }
3795
3796 return ps;
3797 }
3798
Dianne Hackbornb5e31652010-09-07 12:13:55 -07003799 public SparseArray<? extends Pid> getPidStats() {
3800 return mPids;
3801 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003802
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003803 public Pid getPidStatsLocked(int pid) {
3804 Pid p = mPids.get(pid);
3805 if (p == null) {
3806 p = new Pid();
3807 mPids.put(pid, p);
3808 }
3809 return p;
3810 }
3811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 /**
3813 * Retrieve the statistics object for a particular service, creating
3814 * if needed.
3815 */
3816 public Pkg getPackageStatsLocked(String name) {
3817 Pkg ps = mPackageStats.get(name);
3818 if (ps == null) {
3819 ps = new Pkg();
3820 mPackageStats.put(name, ps);
3821 }
3822
3823 return ps;
3824 }
3825
3826 /**
3827 * Retrieve the statistics object for a particular service, creating
3828 * if needed.
3829 */
3830 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
3831 Pkg ps = getPackageStatsLocked(pkg);
3832 Pkg.Serv ss = ps.mServiceStats.get(serv);
3833 if (ss == null) {
3834 ss = ps.newServiceStatsLocked();
3835 ps.mServiceStats.put(serv, ss);
3836 }
3837
3838 return ss;
3839 }
3840
Evan Millarc64edde2009-04-18 12:26:32 -07003841 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 Wakelock wl = mWakelockStats.get(name);
3843 if (wl == null) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08003844 if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) {
3845 name = BATCHED_WAKELOCK_NAME;
3846 wl = mWakelockStats.get(name);
3847 }
3848 if (wl == null) {
3849 wl = new Wakelock();
3850 mWakelockStats.put(name, wl);
3851 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003852 }
Evan Millarc64edde2009-04-18 12:26:32 -07003853 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003854 switch (type) {
3855 case WAKE_TYPE_PARTIAL:
3856 t = wl.mTimerPartial;
3857 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003858 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
3859 mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003860 wl.mTimerPartial = t;
3861 }
3862 return t;
3863 case WAKE_TYPE_FULL:
3864 t = wl.mTimerFull;
3865 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003866 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
3867 mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003868 wl.mTimerFull = t;
3869 }
3870 return t;
3871 case WAKE_TYPE_WINDOW:
3872 t = wl.mTimerWindow;
3873 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003874 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
3875 mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 wl.mTimerWindow = t;
3877 }
3878 return t;
3879 default:
3880 throw new IllegalArgumentException("type=" + type);
3881 }
3882 }
3883
Evan Millarc64edde2009-04-18 12:26:32 -07003884 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003885 Sensor se = mSensorStats.get(sensor);
3886 if (se == null) {
3887 if (!create) {
3888 return null;
3889 }
3890 se = new Sensor(sensor);
3891 mSensorStats.put(sensor, se);
3892 }
Evan Millarc64edde2009-04-18 12:26:32 -07003893 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003894 if (t != null) {
3895 return t;
3896 }
Evan Millarc64edde2009-04-18 12:26:32 -07003897 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003899 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003900 mSensorTimers.put(sensor, timers);
3901 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003902 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003903 se.mTimer = t;
3904 return t;
3905 }
3906
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003907 public void noteStartWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003908 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003909 if (t != null) {
3910 t.startRunningLocked(BatteryStatsImpl.this);
3911 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003912 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003913 Pid p = getPidStatsLocked(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003914 if (p.mWakeStart == 0) {
3915 p.mWakeStart = SystemClock.elapsedRealtime();
3916 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 }
3919
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003920 public void noteStopWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003921 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003922 if (t != null) {
3923 t.stopRunningLocked(BatteryStatsImpl.this);
3924 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003925 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003926 Pid p = mPids.get(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003927 if (p != null && p.mWakeStart != 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003928 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
3929 p.mWakeStart = 0;
3930 }
3931 }
3932 }
3933
3934 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
3935 Proc p = getProcessStatsLocked(proc);
3936 if (p != null) {
3937 p.addExcessiveWake(overTime, usedTime);
3938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003939 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003940
Dianne Hackborn287952c2010-09-22 22:34:31 -07003941 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
3942 Proc p = getProcessStatsLocked(proc);
3943 if (p != null) {
3944 p.addExcessiveCpu(overTime, usedTime);
3945 }
3946 }
3947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07003949 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003950 if (t != null) {
3951 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 }
3954
3955 public void noteStopSensor(int sensor) {
3956 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07003957 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 if (t != null) {
3959 t.stopRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003960 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07003964 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 if (t != null) {
3966 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003967 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07003971 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 if (t != null) {
3973 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003974 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003975 }
3976
3977 public BatteryStatsImpl getBatteryStats() {
3978 return BatteryStatsImpl.this;
3979 }
3980 }
3981
3982 public BatteryStatsImpl(String filename) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003983 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003984 mHandler = new MyHandler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003985 mStartCount++;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003986 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003987 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003988 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003989 }
3990 mInputEventCounter = new Counter(mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003991 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
Wink Saville52840902011-02-18 12:40:47 -08003992 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003993 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003994 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003995 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003996 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003997 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003998 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003999 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004000 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004001 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
4002 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
4003 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004005 initTimes();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004006 mTrackBatteryPastUptime = 0;
4007 mTrackBatteryPastRealtime = 0;
4008 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4009 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4010 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4011 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07004012 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004013 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07004014 mDischargeCurrentLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004015 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004016 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004017 }
4018
4019 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004020 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004021 mHandler = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004022 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 readFromParcel(p);
4024 }
4025
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004026 public void setCallback(BatteryCallback cb) {
4027 mCallback = cb;
4028 }
4029
Amith Yamasanie43530a2009-08-21 13:11:37 -07004030 public void setNumSpeedSteps(int steps) {
4031 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
4032 }
4033
Amith Yamasanif37447b2009-10-08 18:28:01 -07004034 public void setRadioScanningTimeout(long timeout) {
4035 if (mPhoneSignalScanningTimer != null) {
4036 mPhoneSignalScanningTimer.setTimeout(timeout);
4037 }
4038 }
4039
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004040 @Override
4041 public boolean startIteratingOldHistoryLocked() {
4042 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4043 + " pos=" + mHistoryBuffer.dataPosition());
4044 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004045 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004046 mReadOverflow = false;
4047 mIteratingHistory = true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004048 return (mHistoryIterator = mHistory) != null;
4049 }
4050
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004051 @Override
4052 public boolean getNextOldHistoryLocked(HistoryItem out) {
4053 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
4054 if (!end) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004055 mHistoryReadTmp.readDelta(mHistoryBuffer);
4056 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004057 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004058 HistoryItem cur = mHistoryIterator;
4059 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004060 if (!mReadOverflow && !end) {
4061 Slog.w(TAG, "Old history ends before new history!");
4062 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004063 return false;
4064 }
4065 out.setTo(cur);
4066 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004067 if (!mReadOverflow) {
4068 if (end) {
4069 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004070 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004071 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
4072 PrintWriter pw = new PrintWriter(new LogWriter(android.util.Log.WARN, TAG));
4073 pw.println("Histories differ!");
4074 pw.println("Old history:");
4075 (new HistoryPrinter()).printNextItem(pw, out, now);
4076 pw.println("New history:");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004077 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004078 }
4079 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004080 return true;
4081 }
4082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004083 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004084 public void finishIteratingOldHistoryLocked() {
4085 mIteratingHistory = false;
4086 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
4087 }
4088
4089 @Override
4090 public boolean startIteratingHistoryLocked() {
4091 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4092 + " pos=" + mHistoryBuffer.dataPosition());
4093 mHistoryBuffer.setDataPosition(0);
4094 mReadOverflow = false;
4095 mIteratingHistory = true;
4096 return mHistoryBuffer.dataSize() > 0;
4097 }
4098
4099 @Override
4100 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004101 final int pos = mHistoryBuffer.dataPosition();
4102 if (pos == 0) {
4103 out.clear();
4104 }
4105 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004106 if (end) {
4107 return false;
4108 }
4109
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004110 out.readDelta(mHistoryBuffer);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004111 return true;
4112 }
4113
4114 @Override
4115 public void finishIteratingHistoryLocked() {
4116 mIteratingHistory = false;
4117 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004118 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004119
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004120 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004121 public long getHistoryBaseTime() {
4122 return mHistoryBaseTime;
4123 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004124
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004125 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004126 public int getStartCount() {
4127 return mStartCount;
4128 }
4129
4130 public boolean isOnBattery() {
4131 return mOnBattery;
4132 }
4133
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004134 public boolean isScreenOn() {
4135 return mScreenOn;
4136 }
4137
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004138 void initTimes() {
4139 mBatteryRealtime = mTrackBatteryPastUptime = 0;
4140 mBatteryUptime = mTrackBatteryPastRealtime = 0;
4141 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4142 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4143 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4144 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
4145 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004146
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004147 void initDischarge() {
4148 mLowDischargeAmountSinceCharge = 0;
4149 mHighDischargeAmountSinceCharge = 0;
4150 mDischargeAmountScreenOn = 0;
4151 mDischargeAmountScreenOnSinceCharge = 0;
4152 mDischargeAmountScreenOff = 0;
4153 mDischargeAmountScreenOffSinceCharge = 0;
4154 }
4155
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004156 public void resetAllStatsLocked() {
4157 mStartCount = 0;
4158 initTimes();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004159 mScreenOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004160 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004161 mScreenBrightnessTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004162 }
4163 mInputEventCounter.reset(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004164 mPhoneOnTimer.reset(this, false);
4165 mAudioOnTimer.reset(this, false);
4166 mVideoOnTimer.reset(this, false);
Wink Saville52840902011-02-18 12:40:47 -08004167 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004168 mPhoneSignalStrengthsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004169 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004170 mPhoneSignalScanningTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004171 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004172 mPhoneDataConnectionsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004173 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004174 mWifiOnTimer.reset(this, false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004175 mGlobalWifiRunningTimer.reset(this, false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004176 mBluetoothOnTimer.reset(this, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004177
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004178 for (int i=0; i<mUidStats.size(); i++) {
4179 if (mUidStats.valueAt(i).reset()) {
4180 mUidStats.remove(mUidStats.keyAt(i));
4181 i--;
4182 }
4183 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004184
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004185 if (mKernelWakelockStats.size() > 0) {
4186 for (SamplingTimer timer : mKernelWakelockStats.values()) {
4187 mUnpluggables.remove(timer);
4188 }
4189 mKernelWakelockStats.clear();
4190 }
4191
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004192 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004193
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004194 clearHistoryLocked();
4195 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004196
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004197 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004198 if (oldScreenOn) {
4199 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
4200 if (diff > 0) {
4201 mDischargeAmountScreenOn += diff;
4202 mDischargeAmountScreenOnSinceCharge += diff;
4203 }
4204 } else {
4205 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
4206 if (diff > 0) {
4207 mDischargeAmountScreenOff += diff;
4208 mDischargeAmountScreenOffSinceCharge += diff;
4209 }
4210 }
4211 if (newScreenOn) {
4212 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
4213 mDischargeScreenOffUnplugLevel = 0;
4214 } else {
4215 mDischargeScreenOnUnplugLevel = 0;
4216 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
4217 }
4218 }
4219
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004220 void setOnBattery(boolean onBattery, int oldStatus, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004221 synchronized(this) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004222 setOnBatteryLocked(onBattery, oldStatus, level);
4223 }
4224 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004225
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004226 void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
4227 boolean doWrite = false;
4228 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
4229 m.arg1 = onBattery ? 1 : 0;
4230 mHandler.sendMessage(m);
4231 mOnBattery = mOnBatteryInternal = onBattery;
4232
4233 long uptime = SystemClock.uptimeMillis() * 1000;
4234 long mSecRealtime = SystemClock.elapsedRealtime();
4235 long realtime = mSecRealtime * 1000;
4236 if (onBattery) {
4237 // We will reset our status if we are unplugging after the
4238 // battery was last full, or the level is at 100, or
4239 // we have gone through a significant charge (from a very low
4240 // level to a now very high level).
4241 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
4242 || level >= 90
4243 || (mDischargeCurrentLevel < 20 && level >= 80)) {
4244 doWrite = true;
4245 resetAllStatsLocked();
4246 mDischargeStartLevel = level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004247 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004248 updateKernelWakelocksLocked();
4249 mHistoryCur.batteryLevel = (byte)level;
4250 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4251 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
4252 + Integer.toHexString(mHistoryCur.states));
4253 addHistoryRecordLocked(mSecRealtime);
4254 mTrackBatteryUptimeStart = uptime;
4255 mTrackBatteryRealtimeStart = realtime;
4256 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
4257 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
4258 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
4259 if (mScreenOn) {
4260 mDischargeScreenOnUnplugLevel = level;
4261 mDischargeScreenOffUnplugLevel = 0;
4262 } else {
4263 mDischargeScreenOnUnplugLevel = 0;
4264 mDischargeScreenOffUnplugLevel = level;
4265 }
4266 mDischargeAmountScreenOn = 0;
4267 mDischargeAmountScreenOff = 0;
4268 doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
4269 } else {
4270 updateKernelWakelocksLocked();
4271 mHistoryCur.batteryLevel = (byte)level;
4272 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4273 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
4274 + Integer.toHexString(mHistoryCur.states));
4275 addHistoryRecordLocked(mSecRealtime);
4276 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
4277 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
4278 mDischargeCurrentLevel = level;
4279 if (level < mDischargeUnplugLevel) {
4280 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
4281 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
4282 }
4283 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
4284 doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
4285 }
4286 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
4287 if (mFile != null) {
4288 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004289 }
4290 }
4291 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004292
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004293 // This should probably be exposed in the API, though it's not critical
4294 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004295
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004296 public void setBatteryState(int status, int health, int plugType, int level,
4297 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004298 synchronized(this) {
4299 boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
4300 int oldStatus = mHistoryCur.batteryStatus;
4301 if (!mHaveBatteryLevel) {
4302 mHaveBatteryLevel = true;
4303 // We start out assuming that the device is plugged in (not
4304 // on battery). If our first report is now that we are indeed
4305 // plugged in, then twiddle our state to correctly reflect that
4306 // since we won't be going through the full setOnBattery().
4307 if (onBattery == mOnBattery) {
4308 if (onBattery) {
4309 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4310 } else {
4311 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4312 }
4313 }
4314 oldStatus = status;
4315 }
4316 if (onBattery) {
4317 mDischargeCurrentLevel = level;
4318 mRecordingHistory = true;
4319 }
4320 if (onBattery != mOnBattery) {
4321 mHistoryCur.batteryLevel = (byte)level;
4322 mHistoryCur.batteryStatus = (byte)status;
4323 mHistoryCur.batteryHealth = (byte)health;
4324 mHistoryCur.batteryPlugType = (byte)plugType;
4325 mHistoryCur.batteryTemperature = (char)temp;
4326 mHistoryCur.batteryVoltage = (char)volt;
4327 setOnBatteryLocked(onBattery, oldStatus, level);
4328 } else {
4329 boolean changed = false;
4330 if (mHistoryCur.batteryLevel != level) {
4331 mHistoryCur.batteryLevel = (byte)level;
4332 changed = true;
4333 }
4334 if (mHistoryCur.batteryStatus != status) {
4335 mHistoryCur.batteryStatus = (byte)status;
4336 changed = true;
4337 }
4338 if (mHistoryCur.batteryHealth != health) {
4339 mHistoryCur.batteryHealth = (byte)health;
4340 changed = true;
4341 }
4342 if (mHistoryCur.batteryPlugType != plugType) {
4343 mHistoryCur.batteryPlugType = (byte)plugType;
4344 changed = true;
4345 }
4346 if (temp >= (mHistoryCur.batteryTemperature+10)
4347 || temp <= (mHistoryCur.batteryTemperature-10)) {
4348 mHistoryCur.batteryTemperature = (char)temp;
4349 changed = true;
4350 }
4351 if (volt > (mHistoryCur.batteryVoltage+20)
4352 || volt < (mHistoryCur.batteryVoltage-20)) {
4353 mHistoryCur.batteryVoltage = (char)volt;
4354 changed = true;
4355 }
4356 if (changed) {
4357 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004358 }
4359 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004360 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
4361 // We don't record history while we are plugged in and fully charged.
4362 // The next time we are unplugged, history will be cleared.
4363 mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004364 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004365 }
Evan Millar633a1742009-04-02 16:36:33 -07004366 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004367
Evan Millarc64edde2009-04-18 12:26:32 -07004368 public void updateKernelWakelocksLocked() {
4369 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004370
Marco Nelissend8593312009-04-30 14:45:06 -07004371 if (m == null) {
4372 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004373 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07004374 return;
4375 }
4376
Evan Millarc64edde2009-04-18 12:26:32 -07004377 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
4378 String name = ent.getKey();
4379 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004380
Evan Millarc64edde2009-04-18 12:26:32 -07004381 SamplingTimer kwlt = mKernelWakelockStats.get(name);
4382 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004383 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07004384 true /* track reported values */);
4385 mKernelWakelockStats.put(name, kwlt);
4386 }
4387 kwlt.updateCurrentReportedCount(kws.mCount);
4388 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
4389 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
4390 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004391
Evan Millarc64edde2009-04-18 12:26:32 -07004392 if (m.size() != mKernelWakelockStats.size()) {
4393 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
4394 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4395 SamplingTimer st = ent.getValue();
4396 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
4397 st.setStale();
4398 }
4399 }
4400 }
4401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004402
4403 public long getAwakeTimeBattery() {
4404 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
4405 }
4406
4407 public long getAwakeTimePlugged() {
4408 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
4409 }
4410
4411 @Override
4412 public long computeUptime(long curTime, int which) {
4413 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004414 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415 case STATS_LAST: return mLastUptime;
4416 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004417 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004418 }
4419 return 0;
4420 }
4421
4422 @Override
4423 public long computeRealtime(long curTime, int which) {
4424 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004425 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004426 case STATS_LAST: return mLastRealtime;
4427 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004428 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004429 }
4430 return 0;
4431 }
4432
4433 @Override
4434 public long computeBatteryUptime(long curTime, int which) {
4435 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004436 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 return mBatteryUptime + getBatteryUptime(curTime);
4438 case STATS_LAST:
4439 return mBatteryLastUptime;
4440 case STATS_CURRENT:
4441 return getBatteryUptime(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004442 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004443 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
4444 }
4445 return 0;
4446 }
4447
4448 @Override
4449 public long computeBatteryRealtime(long curTime, int which) {
4450 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004451 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004452 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
4453 case STATS_LAST:
4454 return mBatteryLastRealtime;
4455 case STATS_CURRENT:
4456 return getBatteryRealtimeLocked(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004457 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004458 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
4459 }
4460 return 0;
4461 }
4462
4463 long getBatteryUptimeLocked(long curTime) {
4464 long time = mTrackBatteryPastUptime;
4465 if (mOnBatteryInternal) {
4466 time += curTime - mTrackBatteryUptimeStart;
4467 }
4468 return time;
4469 }
4470
4471 long getBatteryUptimeLocked() {
4472 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
4473 }
4474
4475 @Override
4476 public long getBatteryUptime(long curTime) {
4477 return getBatteryUptimeLocked(curTime);
4478 }
4479
4480 long getBatteryRealtimeLocked(long curTime) {
4481 long time = mTrackBatteryPastRealtime;
4482 if (mOnBatteryInternal) {
4483 time += curTime - mTrackBatteryRealtimeStart;
4484 }
4485 return time;
4486 }
4487
4488 @Override
4489 public long getBatteryRealtime(long curTime) {
4490 return getBatteryRealtimeLocked(curTime);
4491 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004492
4493 private long getTcpBytes(long current, long[] dataBytes, int which) {
4494 if (which == STATS_LAST) {
4495 return dataBytes[STATS_LAST];
4496 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004497 if (which == STATS_SINCE_UNPLUGGED) {
4498 if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004499 return dataBytes[STATS_LAST];
4500 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004501 return current - dataBytes[STATS_SINCE_UNPLUGGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004502 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004503 } else if (which == STATS_SINCE_CHARGED) {
4504 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004505 }
4506 return current - dataBytes[STATS_CURRENT];
4507 }
4508 }
4509
4510 /** Only STATS_UNPLUGGED works properly */
4511 public long getMobileTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004512 return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004513 }
4514
4515 /** Only STATS_UNPLUGGED works properly */
4516 public long getMobileTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004517 return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004518 }
4519
4520 /** Only STATS_UNPLUGGED works properly */
4521 public long getTotalTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004522 return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004523 }
4524
4525 /** Only STATS_UNPLUGGED works properly */
4526 public long getTotalTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08004527 return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004528 }
4529
The Android Open Source Project10592532009-03-18 17:39:46 -07004530 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004531 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004532 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004533 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004534 }
4535 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004536
Evan Millar633a1742009-04-02 16:36:33 -07004537 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004538 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004539 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004540
The Android Open Source Project10592532009-03-18 17:39:46 -07004541 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004542 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004543 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004544 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004545 }
4546 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004547
Evan Millar633a1742009-04-02 16:36:33 -07004548 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004549 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551
Amith Yamasanie43530a2009-08-21 13:11:37 -07004552 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004553 public int getLowDischargeAmountSinceCharge() {
4554 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004555 int val = mLowDischargeAmountSinceCharge;
4556 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4557 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
4558 }
4559 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004560 }
4561 }
4562
4563 @Override
4564 public int getHighDischargeAmountSinceCharge() {
4565 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004566 int val = mHighDischargeAmountSinceCharge;
4567 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4568 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
4569 }
4570 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004571 }
4572 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004573
4574 public int getDischargeAmountScreenOn() {
4575 synchronized(this) {
4576 int val = mDischargeAmountScreenOn;
4577 if (mOnBattery && mScreenOn
4578 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4579 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4580 }
4581 return val;
4582 }
4583 }
4584
4585 public int getDischargeAmountScreenOnSinceCharge() {
4586 synchronized(this) {
4587 int val = mDischargeAmountScreenOnSinceCharge;
4588 if (mOnBattery && mScreenOn
4589 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4590 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4591 }
4592 return val;
4593 }
4594 }
4595
4596 public int getDischargeAmountScreenOff() {
4597 synchronized(this) {
4598 int val = mDischargeAmountScreenOff;
4599 if (mOnBattery && !mScreenOn
4600 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4601 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4602 }
4603 return val;
4604 }
4605 }
4606
4607 public int getDischargeAmountScreenOffSinceCharge() {
4608 synchronized(this) {
4609 int val = mDischargeAmountScreenOffSinceCharge;
4610 if (mOnBattery && !mScreenOn
4611 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4612 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4613 }
4614 return val;
4615 }
4616 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004617
4618 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07004619 public int getCpuSpeedSteps() {
4620 return sNumSpeedSteps;
4621 }
4622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623 /**
4624 * Retrieve the statistics object for a particular uid, creating if needed.
4625 */
4626 public Uid getUidStatsLocked(int uid) {
4627 Uid u = mUidStats.get(uid);
4628 if (u == null) {
4629 u = new Uid(uid);
4630 mUidStats.put(uid, u);
4631 }
4632 return u;
4633 }
4634
4635 /**
4636 * Remove the statistics object for a particular uid.
4637 */
4638 public void removeUidStatsLocked(int uid) {
4639 mUidStats.remove(uid);
4640 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 /**
4643 * Retrieve the statistics object for a particular process, creating
4644 * if needed.
4645 */
4646 public Uid.Proc getProcessStatsLocked(int uid, String name) {
4647 Uid u = getUidStatsLocked(uid);
4648 return u.getProcessStatsLocked(name);
4649 }
4650
4651 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004652 * Retrieve the statistics object for a particular process, given
4653 * the name of the process.
4654 * @param name process name
4655 * @return the statistics object for the process
4656 */
Amith Yamasani819f9282009-06-24 23:18:15 -07004657 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004658 int uid;
4659 if (mUidCache.containsKey(name)) {
4660 uid = mUidCache.get(name);
4661 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07004662 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004663 mUidCache.put(name, uid);
4664 }
4665 Uid u = getUidStatsLocked(uid);
4666 return u.getProcessStatsLocked(name);
4667 }
4668
4669 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004670 * Retrieve the statistics object for a particular process, creating
4671 * if needed.
4672 */
4673 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
4674 Uid u = getUidStatsLocked(uid);
4675 return u.getPackageStatsLocked(pkg);
4676 }
4677
4678 /**
4679 * Retrieve the statistics object for a particular service, creating
4680 * if needed.
4681 */
4682 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
4683 Uid u = getUidStatsLocked(uid);
4684 return u.getServiceStatsLocked(pkg, name);
4685 }
4686
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004687 /**
4688 * Massage data to distribute any reasonable work down to more specific
4689 * owners. Must only be called on a dead BatteryStats object!
4690 */
4691 public void distributeWorkLocked(int which) {
4692 // Aggregate all CPU time associated with WIFI.
4693 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
4694 if (wifiUid != null) {
4695 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
4696 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
4697 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
4698 for (int i=0; i<mUidStats.size(); i++) {
4699 Uid uid = mUidStats.valueAt(i);
4700 if (uid.mUid != Process.WIFI_UID) {
4701 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
4702 if (uidRunningTime > 0) {
4703 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
4704 long time = proc.getUserTime(which);
4705 time = (time*uidRunningTime)/totalRunningTime;
4706 uidProc.mUserTime += time;
4707 proc.mUserTime -= time;
4708 time = proc.getSystemTime(which);
4709 time = (time*uidRunningTime)/totalRunningTime;
4710 uidProc.mSystemTime += time;
4711 proc.mSystemTime -= time;
4712 time = proc.getForegroundTime(which);
4713 time = (time*uidRunningTime)/totalRunningTime;
4714 uidProc.mForegroundTime += time;
4715 proc.mForegroundTime -= time;
4716 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
4717 SamplingCounter sc = proc.mSpeedBins[sb];
4718 if (sc != null) {
4719 time = sc.getCountLocked(which);
4720 time = (time*uidRunningTime)/totalRunningTime;
4721 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
4722 if (uidSc == null) {
4723 uidSc = new SamplingCounter(mUnpluggables);
4724 uidProc.mSpeedBins[sb] = uidSc;
4725 }
4726 uidSc.mCount.addAndGet((int)time);
4727 sc.mCount.addAndGet((int)-time);
4728 }
4729 }
4730 totalRunningTime -= uidRunningTime;
4731 }
4732 }
4733 }
4734 }
4735 }
4736 }
4737
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004738 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004739 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004740 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004741 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004742
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004743 Parcel mPendingWrite = null;
4744 final ReentrantLock mWriteLock = new ReentrantLock();
4745
4746 public void writeAsyncLocked() {
4747 writeLocked(false);
4748 }
4749
4750 public void writeSyncLocked() {
4751 writeLocked(true);
4752 }
4753
4754 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004755 if (mFile == null) {
4756 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004757 return;
4758 }
4759
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004760 if (mShuttingDown) {
4761 return;
4762 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004763
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004764 Parcel out = Parcel.obtain();
4765 writeSummaryToParcel(out);
4766 mLastWriteTime = SystemClock.elapsedRealtime();
4767
4768 if (mPendingWrite != null) {
4769 mPendingWrite.recycle();
4770 }
4771 mPendingWrite = out;
4772
4773 if (sync) {
4774 commitPendingDataToDisk();
4775 } else {
4776 Thread thr = new Thread("BatteryStats-Write") {
4777 @Override
4778 public void run() {
4779 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
4780 commitPendingDataToDisk();
4781 }
4782 };
4783 thr.start();
4784 }
4785 }
4786
4787 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004788 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004789 synchronized (this) {
4790 next = mPendingWrite;
4791 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004792 if (next == null) {
4793 return;
4794 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004795
4796 mWriteLock.lock();
4797 }
4798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004800 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004801 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07004803 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004804 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004805 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004806 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004807 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004808 mFile.rollback();
4809 } finally {
4810 next.recycle();
4811 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07004812 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004813 }
4814
4815 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
4816 int pos = 0;
4817 int avail = stream.available();
4818 byte[] data = new byte[avail];
4819 while (true) {
4820 int amt = stream.read(data, pos, data.length-pos);
4821 //Log.i("foo", "Read " + amt + " bytes at " + pos
4822 // + " of avail " + data.length);
4823 if (amt <= 0) {
4824 //Log.i("foo", "**** FINISHED READING: pos=" + pos
4825 // + " len=" + data.length);
4826 return data;
4827 }
4828 pos += amt;
4829 avail = stream.available();
4830 if (avail > data.length-pos) {
4831 byte[] newData = new byte[pos+avail];
4832 System.arraycopy(data, 0, newData, 0, pos);
4833 data = newData;
4834 }
4835 }
4836 }
4837
4838 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004839 if (mFile == null) {
4840 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004841 return;
4842 }
4843
4844 mUidStats.clear();
4845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004846 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004847 File file = mFile.chooseForRead();
4848 if (!file.exists()) {
4849 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004850 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004851 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004852
4853 byte[] raw = readFully(stream);
4854 Parcel in = Parcel.obtain();
4855 in.unmarshall(raw, 0, raw.length);
4856 in.setDataPosition(0);
4857 stream.close();
4858
4859 readSummaryFromParcel(in);
4860 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004861 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004862 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004863
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004864 long now = SystemClock.elapsedRealtime();
4865 addHistoryRecordLocked(now, HistoryItem.CMD_START);
4866 addHistoryBufferLocked(now, HistoryItem.CMD_START);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 }
4868
4869 public int describeContents() {
4870 return 0;
4871 }
4872
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004873 void readHistory(Parcel in) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004874 mHistoryBaseTime = in.readLong();
4875
4876 mHistoryBuffer.setDataSize(0);
4877 mHistoryBuffer.setDataPosition(0);
4878
4879 int bufSize = in.readInt();
4880 int curPos = in.dataPosition();
4881 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
4882 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
4883 } else if ((bufSize&~3) != bufSize) {
4884 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
4885 } else {
4886 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
4887 + " bytes at " + curPos);
4888 mHistoryBuffer.appendFrom(in, curPos, bufSize);
4889 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004890 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004891
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004892 long oldnow = SystemClock.elapsedRealtime() - (5*60*1000);
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07004893 if (oldnow > 0) {
4894 // If the system process has restarted, but not the entire
4895 // system, then the mHistoryBaseTime already accounts for
4896 // much of the elapsed time. We thus want to adjust it back,
4897 // to avoid large gaps in the data. We determine we are
4898 // in this case by arbitrarily saying it is so if at this
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004899 // point in boot the elapsed time is already more than 5 minutes.
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07004900 mHistoryBaseTime -= oldnow;
4901 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004902 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004903
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004904 void readOldHistory(Parcel in) {
4905 mHistory = mHistoryEnd = mHistoryCache = null;
4906 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07004907 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004908 HistoryItem rec = new HistoryItem(time, in);
4909 addHistoryRecordLocked(rec);
4910 }
4911 }
4912
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004913 void writeHistory(Parcel out) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004914 out.writeLong(mLastHistoryTime);
4915 out.writeInt(mHistoryBuffer.dataSize());
4916 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
4917 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
4918 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
4919 }
4920
4921 void writeOldHistory(Parcel out) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004922 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004923 while (rec != null) {
4924 if (rec.time >= 0) rec.writeToParcel(out, 0);
4925 rec = rec.next;
4926 }
4927 out.writeLong(-1);
4928 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004929
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004930 private void readSummaryFromParcel(Parcel in) {
4931 final int version = in.readInt();
4932 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004933 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004934 + ", expected " + VERSION + "; erasing old stats");
4935 return;
4936 }
4937
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004938 readHistory(in);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004939 readOldHistory(in);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004941 mStartCount = in.readInt();
4942 mBatteryUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004943 mBatteryRealtime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004944 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 mRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004946 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07004947 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004948 mLowDischargeAmountSinceCharge = in.readInt();
4949 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004950 mDischargeAmountScreenOnSinceCharge = in.readInt();
4951 mDischargeAmountScreenOffSinceCharge = in.readInt();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004953 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004955 mScreenOn = false;
4956 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004957 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4958 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
4959 }
4960 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004961 mPhoneOn = false;
4962 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08004963 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07004964 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
4965 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004966 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004967 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4968 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
4969 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004970 mWifiOn = false;
4971 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004972 mGlobalWifiRunning = false;
4973 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07004974 mBluetoothOn = false;
4975 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976
Evan Millarc64edde2009-04-18 12:26:32 -07004977 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004978 if (NKW > 10000) {
4979 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
4980 return;
4981 }
Evan Millarc64edde2009-04-18 12:26:32 -07004982 for (int ikw = 0; ikw < NKW; ikw++) {
4983 if (in.readInt() != 0) {
4984 String kwltName = in.readString();
4985 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
4986 }
4987 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004988
4989 sNumSpeedSteps = in.readInt();
4990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004991 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004992 if (NU > 10000) {
4993 Slog.w(TAG, "File corrupt: too many uids " + NU);
4994 return;
4995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004996 for (int iu = 0; iu < NU; iu++) {
4997 int uid = in.readInt();
4998 Uid u = new Uid(uid);
4999 mUidStats.put(uid, u);
5000
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005001 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005002 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005003 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005004 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005005 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005006 if (in.readInt() != 0) {
5007 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
5008 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005009 u.mScanWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005010 if (in.readInt() != 0) {
5011 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
5012 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005013 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005014 if (in.readInt() != 0) {
5015 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
5016 }
5017 u.mAudioTurnedOn = false;
5018 if (in.readInt() != 0) {
5019 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
5020 }
5021 u.mVideoTurnedOn = false;
5022 if (in.readInt() != 0) {
5023 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
5024 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005025
Dianne Hackborn617f8772009-03-31 15:04:46 -07005026 if (in.readInt() != 0) {
5027 if (u.mUserActivityCounters == null) {
5028 u.initUserActivityLocked();
5029 }
5030 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5031 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
5032 }
5033 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005035 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005036 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005037 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
5038 return;
5039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005040 for (int iw = 0; iw < NW; iw++) {
5041 String wlName = in.readString();
5042 if (in.readInt() != 0) {
5043 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
5044 }
5045 if (in.readInt() != 0) {
5046 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
5047 }
5048 if (in.readInt() != 0) {
5049 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
5050 }
5051 }
5052
5053 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005054 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005055 Slog.w(TAG, "File corrupt: too many sensors " + NP);
5056 return;
5057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005058 for (int is = 0; is < NP; is++) {
5059 int seNumber = in.readInt();
5060 if (in.readInt() != 0) {
5061 u.getSensorTimerLocked(seNumber, true)
5062 .readSummaryFromParcelLocked(in);
5063 }
5064 }
5065
5066 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005067 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005068 Slog.w(TAG, "File corrupt: too many processes " + NP);
5069 return;
5070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005071 for (int ip = 0; ip < NP; ip++) {
5072 String procName = in.readString();
5073 Uid.Proc p = u.getProcessStatsLocked(procName);
5074 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005075 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005076 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005077 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005078 if (NSB > 100) {
5079 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
5080 return;
5081 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005082 p.mSpeedBins = new SamplingCounter[NSB];
5083 for (int i=0; i<NSB; i++) {
5084 if (in.readInt() != 0) {
5085 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables);
5086 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
5087 }
5088 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005089 if (!p.readExcessivePowerFromParcelLocked(in)) {
5090 return;
5091 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005092 }
5093
5094 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005095 if (NP > 10000) {
5096 Slog.w(TAG, "File corrupt: too many packages " + NP);
5097 return;
5098 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005099 for (int ip = 0; ip < NP; ip++) {
5100 String pkgName = in.readString();
5101 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
5102 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005103 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005104 if (NS > 1000) {
5105 Slog.w(TAG, "File corrupt: too many services " + NS);
5106 return;
5107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005108 for (int is = 0; is < NS; is++) {
5109 String servName = in.readString();
5110 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
5111 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005112 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005113 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 }
5115 }
5116
5117 u.mLoadedTcpBytesReceived = in.readLong();
5118 u.mLoadedTcpBytesSent = in.readLong();
5119 }
5120 }
5121
5122 /**
5123 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
5124 * disk. This format does not allow a lossless round-trip.
5125 *
5126 * @param out the Parcel to be written to.
5127 */
5128 public void writeSummaryToParcel(Parcel out) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005129 // Need to update with current kernel wake lock counts.
5130 updateKernelWakelocksLocked();
5131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005132 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
5133 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
5134 final long NOW = getBatteryUptimeLocked(NOW_SYS);
5135 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
5136
5137 out.writeInt(VERSION);
5138
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005139 writeHistory(out);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005140 writeOldHistory(out);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005142 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005143 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005144 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005145 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005146 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005147 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005148 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08005149 out.writeInt(getLowDischargeAmountSinceCharge());
5150 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005151 out.writeInt(getDischargeAmountScreenOnSinceCharge());
5152 out.writeInt(getDischargeAmountScreenOffSinceCharge());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005153
5154 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005155 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5156 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5157 }
5158 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005159 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Wink Saville52840902011-02-18 12:40:47 -08005160 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005161 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5162 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005163 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005164 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5165 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5166 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005167 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005168 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07005169 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005170
Evan Millarc64edde2009-04-18 12:26:32 -07005171 out.writeInt(mKernelWakelockStats.size());
5172 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5173 Timer kwlt = ent.getValue();
5174 if (kwlt != null) {
5175 out.writeInt(1);
5176 out.writeString(ent.getKey());
5177 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
5178 } else {
5179 out.writeInt(0);
5180 }
5181 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005182
Amith Yamasanie43530a2009-08-21 13:11:37 -07005183 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005184 final int NU = mUidStats.size();
5185 out.writeInt(NU);
5186 for (int iu = 0; iu < NU; iu++) {
5187 out.writeInt(mUidStats.keyAt(iu));
5188 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005189
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005190 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005191 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005192 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005193 } else {
5194 out.writeInt(0);
5195 }
5196 if (u.mFullWifiLockTimer != null) {
5197 out.writeInt(1);
5198 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5199 } else {
5200 out.writeInt(0);
5201 }
5202 if (u.mScanWifiLockTimer != null) {
5203 out.writeInt(1);
5204 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5205 } else {
5206 out.writeInt(0);
5207 }
5208 if (u.mWifiMulticastTimer != null) {
5209 out.writeInt(1);
5210 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5211 } else {
5212 out.writeInt(0);
5213 }
5214 if (u.mAudioTurnedOnTimer != null) {
5215 out.writeInt(1);
5216 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5217 } else {
5218 out.writeInt(0);
5219 }
5220 if (u.mVideoTurnedOnTimer != null) {
5221 out.writeInt(1);
5222 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5223 } else {
5224 out.writeInt(0);
5225 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226
Dianne Hackborn617f8772009-03-31 15:04:46 -07005227 if (u.mUserActivityCounters == null) {
5228 out.writeInt(0);
5229 } else {
5230 out.writeInt(1);
5231 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5232 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
5233 }
5234 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005236 int NW = u.mWakelockStats.size();
5237 out.writeInt(NW);
5238 if (NW > 0) {
5239 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
5240 : u.mWakelockStats.entrySet()) {
5241 out.writeString(ent.getKey());
5242 Uid.Wakelock wl = ent.getValue();
5243 if (wl.mTimerFull != null) {
5244 out.writeInt(1);
5245 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
5246 } else {
5247 out.writeInt(0);
5248 }
5249 if (wl.mTimerPartial != null) {
5250 out.writeInt(1);
5251 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
5252 } else {
5253 out.writeInt(0);
5254 }
5255 if (wl.mTimerWindow != null) {
5256 out.writeInt(1);
5257 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
5258 } else {
5259 out.writeInt(0);
5260 }
5261 }
5262 }
5263
5264 int NSE = u.mSensorStats.size();
5265 out.writeInt(NSE);
5266 if (NSE > 0) {
5267 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
5268 : u.mSensorStats.entrySet()) {
5269 out.writeInt(ent.getKey());
5270 Uid.Sensor se = ent.getValue();
5271 if (se.mTimer != null) {
5272 out.writeInt(1);
5273 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5274 } else {
5275 out.writeInt(0);
5276 }
5277 }
5278 }
5279
5280 int NP = u.mProcessStats.size();
5281 out.writeInt(NP);
5282 if (NP > 0) {
5283 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
5284 : u.mProcessStats.entrySet()) {
5285 out.writeString(ent.getKey());
5286 Uid.Proc ps = ent.getValue();
5287 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005288 out.writeLong(ps.mSystemTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005289 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005290 final int N = ps.mSpeedBins.length;
5291 out.writeInt(N);
5292 for (int i=0; i<N; i++) {
5293 if (ps.mSpeedBins[i] != null) {
5294 out.writeInt(1);
5295 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
5296 } else {
5297 out.writeInt(0);
5298 }
5299 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005300 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005301 }
5302 }
5303
5304 NP = u.mPackageStats.size();
5305 out.writeInt(NP);
5306 if (NP > 0) {
5307 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
5308 : u.mPackageStats.entrySet()) {
5309 out.writeString(ent.getKey());
5310 Uid.Pkg ps = ent.getValue();
5311 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005312 final int NS = ps.mServiceStats.size();
5313 out.writeInt(NS);
5314 if (NS > 0) {
5315 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
5316 : ps.mServiceStats.entrySet()) {
5317 out.writeString(sent.getKey());
5318 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
5319 long time = ss.getStartTimeToNowLocked(NOW);
5320 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005321 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005322 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005323 }
5324 }
5325 }
5326 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005327
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005328 out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED));
5329 out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005330 }
5331 }
5332
5333 public void readFromParcel(Parcel in) {
5334 readFromParcelLocked(in);
5335 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337 void readFromParcelLocked(Parcel in) {
5338 int magic = in.readInt();
5339 if (magic != MAGIC) {
5340 throw new ParcelFormatException("Bad magic number");
5341 }
5342
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005343 readHistory(in);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005345 mStartCount = in.readInt();
5346 mBatteryUptime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005347 mBatteryLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005348 mBatteryRealtime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005349 mBatteryLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005350 mScreenOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005351 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005352 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005353 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i,
5354 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005355 }
5356 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005357 mPhoneOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005358 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Wink Saville52840902011-02-18 12:40:47 -08005359 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005360 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
5361 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005362 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005363 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005364 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005365 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
5366 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005367 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005368 mWifiOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005369 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005370 mGlobalWifiRunning = false;
5371 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005372 mBluetoothOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005373 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005374 mUptime = in.readLong();
5375 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005376 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005377 mRealtime = in.readLong();
5378 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005379 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005380 mOnBattery = in.readInt() != 0;
5381 mOnBatteryInternal = false; // we are no longer really running.
5382 mTrackBatteryPastUptime = in.readLong();
5383 mTrackBatteryUptimeStart = in.readLong();
5384 mTrackBatteryPastRealtime = in.readLong();
5385 mTrackBatteryRealtimeStart = in.readLong();
5386 mUnpluggedBatteryUptime = in.readLong();
5387 mUnpluggedBatteryRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005388 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005389 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005390 mLowDischargeAmountSinceCharge = in.readInt();
5391 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005392 mDischargeAmountScreenOn = in.readInt();
5393 mDischargeAmountScreenOnSinceCharge = in.readInt();
5394 mDischargeAmountScreenOff = in.readInt();
5395 mDischargeAmountScreenOffSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005396 mLastWriteTime = in.readLong();
5397
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005398 mMobileDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005399 mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005400 mMobileDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005401 mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005402 mTotalDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005403 mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005404 mTotalDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005405 mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005406
5407 mRadioDataUptime = in.readLong();
5408 mRadioDataStart = -1;
5409
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005410 mBluetoothPingCount = in.readInt();
5411 mBluetoothPingStart = -1;
5412
Evan Millarc64edde2009-04-18 12:26:32 -07005413 mKernelWakelockStats.clear();
5414 int NKW = in.readInt();
5415 for (int ikw = 0; ikw < NKW; ikw++) {
5416 if (in.readInt() != 0) {
5417 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005418 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07005419 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
5420 mKernelWakelockStats.put(wakelockName, kwlt);
5421 }
5422 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005424 mPartialTimers.clear();
5425 mFullTimers.clear();
5426 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005427 mWifiRunningTimers.clear();
5428 mFullWifiLockTimers.clear();
5429 mScanWifiLockTimers.clear();
5430 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005431
Amith Yamasanie43530a2009-08-21 13:11:37 -07005432 sNumSpeedSteps = in.readInt();
5433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005434 int numUids = in.readInt();
5435 mUidStats.clear();
5436 for (int i = 0; i < numUids; i++) {
5437 int uid = in.readInt();
5438 Uid u = new Uid(uid);
5439 u.readFromParcelLocked(mUnpluggables, in);
5440 mUidStats.append(uid, u);
5441 }
5442 }
5443
5444 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005445 writeToParcelLocked(out, true, flags);
5446 }
5447
5448 public void writeToParcelWithoutUids(Parcel out, int flags) {
5449 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005451
5452 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005453 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005454 // Need to update with current kernel wake lock counts.
5455 updateKernelWakelocksLocked();
5456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005457 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
5458 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
5459 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
5460 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005462 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005463
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005464 writeHistory(out);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 out.writeInt(mStartCount);
5467 out.writeLong(mBatteryUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005468 out.writeLong(mBatteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005469 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005470 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5471 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
5472 }
5473 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005474 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Wink Saville52840902011-02-18 12:40:47 -08005475 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005476 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
5477 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005478 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005479 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5480 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
5481 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005482 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005483 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005484 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005485 out.writeLong(mUptime);
5486 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005487 out.writeLong(mRealtime);
5488 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005489 out.writeInt(mOnBattery ? 1 : 0);
5490 out.writeLong(batteryUptime);
5491 out.writeLong(mTrackBatteryUptimeStart);
5492 out.writeLong(batteryRealtime);
5493 out.writeLong(mTrackBatteryRealtimeStart);
5494 out.writeLong(mUnpluggedBatteryUptime);
5495 out.writeLong(mUnpluggedBatteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005496 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005497 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005498 out.writeInt(mLowDischargeAmountSinceCharge);
5499 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005500 out.writeInt(mDischargeAmountScreenOn);
5501 out.writeInt(mDischargeAmountScreenOnSinceCharge);
5502 out.writeInt(mDischargeAmountScreenOff);
5503 out.writeInt(mDischargeAmountScreenOffSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005504 out.writeLong(mLastWriteTime);
5505
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005506 out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5507 out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED));
5508 out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5509 out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED));
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005510
5511 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005512 out.writeLong(getRadioDataUptime());
5513
5514 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005515
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005516 if (inclUids) {
5517 out.writeInt(mKernelWakelockStats.size());
5518 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5519 SamplingTimer kwlt = ent.getValue();
5520 if (kwlt != null) {
5521 out.writeInt(1);
5522 out.writeString(ent.getKey());
5523 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
5524 } else {
5525 out.writeInt(0);
5526 }
Evan Millarc64edde2009-04-18 12:26:32 -07005527 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005528 } else {
5529 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07005530 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005531
5532 out.writeInt(sNumSpeedSteps);
5533
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005534 if (inclUids) {
5535 int size = mUidStats.size();
5536 out.writeInt(size);
5537 for (int i = 0; i < size; i++) {
5538 out.writeInt(mUidStats.keyAt(i));
5539 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005540
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005541 uid.writeToParcelLocked(out, batteryRealtime);
5542 }
5543 } else {
5544 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005545 }
5546 }
5547
5548 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
5549 new Parcelable.Creator<BatteryStatsImpl>() {
5550 public BatteryStatsImpl createFromParcel(Parcel in) {
5551 return new BatteryStatsImpl(in);
5552 }
5553
5554 public BatteryStatsImpl[] newArray(int size) {
5555 return new BatteryStatsImpl[size];
5556 }
5557 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005558
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005559 public void prepareForDumpLocked() {
5560 // Need to retrieve current kernel wake lock stats before printing.
5561 updateKernelWakelocksLocked();
5562 }
5563
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005564 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005565 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005566 Printer pr = new PrintWriterPrinter(pw);
5567 pr.println("*** Screen timer:");
5568 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005569 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005570 pr.println("*** Screen brightness #" + i + ":");
5571 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005572 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005573 pr.println("*** Input event counter:");
5574 mInputEventCounter.logState(pr, " ");
5575 pr.println("*** Phone timer:");
5576 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08005577 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005578 pr.println("*** Signal strength #" + i + ":");
5579 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005580 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005581 pr.println("*** Signal scanning :");
5582 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005583 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005584 pr.println("*** Data connection type #" + i + ":");
5585 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005586 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005587 pr.println("*** Wifi timer:");
5588 mWifiOnTimer.logState(pr, " ");
5589 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005590 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005591 pr.println("*** Bluetooth timer:");
5592 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005593 }
5594 super.dumpLocked(pw);
5595 }
5596}