blob: 3e96c815e9b69e18d0efa1b65c00002e2777ef5f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070019import static android.net.NetworkStats.IFACE_ALL;
20import static android.net.NetworkStats.UID_ALL;
21import static android.text.format.DateUtils.SECOND_IN_MILLIS;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070022
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070023import android.bluetooth.BluetoothDevice;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070024import android.bluetooth.BluetoothHeadset;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070025import android.content.res.Resources;
26import android.net.ConnectivityManager;
27import android.net.NetworkStats;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070028import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.os.BatteryStats;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070030import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070031import android.os.Handler;
32import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.os.Parcel;
34import android.os.ParcelFormatException;
35import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070036import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.os.SystemClock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070038import android.os.WorkSource;
Amith Yamasanif37447b2009-10-08 18:28:01 -070039import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070040import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070041import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070043import android.util.LogWriter;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070044import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070046import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.util.SparseArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070048import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070050import com.android.internal.R;
51import com.android.internal.net.NetworkStatsFactory;
52import com.android.internal.util.JournaledFile;
53import com.google.android.collect.Sets;
54
Amith Yamasani3718aaa2009-06-09 06:32:35 -070055import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import java.io.File;
57import java.io.FileInputStream;
58import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070059import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070061import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import java.util.ArrayList;
63import java.util.HashMap;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070064import java.util.HashSet;
Evan Millarc64edde2009-04-18 12:26:32 -070065import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070066import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070068import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070069import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
71/**
72 * All information we are collecting about things that can happen that impact
73 * battery life. All times are represented in microseconds except where indicated
74 * otherwise.
75 */
76public final class BatteryStatsImpl extends BatteryStats {
77 private static final String TAG = "BatteryStatsImpl";
78 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070079 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -070080 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070081
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070082 // TODO: remove "tcp" from network methods, since we measure total stats.
83
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070085 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086
87 // Current on-disk Parcel version
Dianne Hackborne8c88e62011-08-17 19:09:09 -070088 private static final int VERSION = 61 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -070089
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070090 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070091 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070092
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070093 // No, really, THIS is the maximum number of items we will record in the history.
94 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
95
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080096 // The maximum number of names wakelocks we will keep track of
97 // per uid; once the limit is reached, we batch the remaining wakelocks
98 // in to one common name.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070099 private static final int MAX_WAKELOCKS_PER_UID = 30;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700100
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700101 // The system process gets more. It is special. Oh so special.
102 // With, you know, special needs. Like this.
103 private static final int MAX_WAKELOCKS_PER_UID_IN_SYSTEM = 50;
104
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800105 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700106
Amith Yamasanie43530a2009-08-21 13:11:37 -0700107 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700109 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700111 static final int MSG_UPDATE_WAKELOCKS = 1;
112 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700113 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700114
115 public interface BatteryCallback {
116 public void batteryNeedsCpuUpdate();
117 public void batteryPowerChanged(boolean onBattery);
118 }
119
120 final class MyHandler extends Handler {
121 @Override
122 public void handleMessage(Message msg) {
123 BatteryCallback cb = mCallback;
124 switch (msg.what) {
125 case MSG_UPDATE_WAKELOCKS:
126 if (cb != null) {
127 cb.batteryNeedsCpuUpdate();
128 }
129 break;
130 case MSG_REPORT_POWER_CHANGE:
131 if (cb != null) {
132 cb.batteryPowerChanged(msg.arg1 != 0);
133 }
134 break;
135 }
136 }
137 }
138
139 private final MyHandler mHandler;
140
141 private BatteryCallback mCallback;
142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 /**
144 * The statistics we have collected organized by uids.
145 */
146 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
147 new SparseArray<BatteryStatsImpl.Uid>();
148
149 // A set of pools of currently active timers. When a timer is queried, we will divide the
150 // elapsed time by the number of active timers to arrive at that timer's share of the time.
151 // In order to do this, we must refresh each timer whenever the number of active timers
152 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700153 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
154 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
155 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
156 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
157 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700158 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
159 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
160 final ArrayList<StopwatchTimer> mScanWifiLockTimers = new ArrayList<StopwatchTimer>();
161 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700163 // Last partial timers we use for distributing CPU usage.
164 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 // These are the objects that will want to do something when the device
167 // is unplugged from power.
168 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700169
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700170 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700171
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700172 long mHistoryBaseTime;
173 boolean mHaveBatteryLevel = false;
174 boolean mRecordingHistory = true;
175 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700176
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700177 static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
178 static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700179 final Parcel mHistoryBuffer = Parcel.obtain();
180 final HistoryItem mHistoryLastWritten = new HistoryItem();
181 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700182 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700183 int mHistoryBufferLastPos = -1;
184 boolean mHistoryOverflow = false;
185 long mLastHistoryTime = 0;
186
187 final HistoryItem mHistoryCur = new HistoryItem();
188
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700189 HistoryItem mHistory;
190 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700191 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700192 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700193
194 private HistoryItem mHistoryIterator;
195 private boolean mReadOverflow;
196 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 int mStartCount;
199
200 long mBatteryUptime;
201 long mBatteryLastUptime;
202 long mBatteryRealtime;
203 long mBatteryLastRealtime;
204
205 long mUptime;
206 long mUptimeStart;
207 long mLastUptime;
208 long mRealtime;
209 long mRealtimeStart;
210 long mLastRealtime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700213 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700214
Dianne Hackborn617f8772009-03-31 15:04:46 -0700215 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700216 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700217
Dianne Hackborn617f8772009-03-31 15:04:46 -0700218 Counter mInputEventCounter;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700221 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700222
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700223 boolean mAudioOn;
224 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700225
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700226 boolean mVideoOn;
227 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700228
Dianne Hackborn627bba72009-03-24 22:32:56 -0700229 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800230 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700231 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800232 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700233
234 StopwatchTimer mPhoneSignalScanningTimer;
235
Dianne Hackborn627bba72009-03-24 22:32:56 -0700236 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700237 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700238 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700239
The Android Open Source Project10592532009-03-18 17:39:46 -0700240 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700241 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700242 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700243
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700244 boolean mGlobalWifiRunning;
245 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700246
The Android Open Source Project10592532009-03-18 17:39:46 -0700247 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700248 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700249
250 /** Bluetooth headset object */
251 BluetoothHeadset mBtHeadset;
252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 /**
254 * These provide time bases that discount the time the device is plugged
255 * in to power.
256 */
257 boolean mOnBattery;
258 boolean mOnBatteryInternal;
259 long mTrackBatteryPastUptime;
260 long mTrackBatteryUptimeStart;
261 long mTrackBatteryPastRealtime;
262 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 long mUnpluggedBatteryUptime;
265 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700266
The Android Open Source Project10592532009-03-18 17:39:46 -0700267 /*
268 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
269 */
Evan Millar633a1742009-04-02 16:36:33 -0700270 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700271 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700272 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700273 int mLowDischargeAmountSinceCharge;
274 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800275 int mDischargeScreenOnUnplugLevel;
276 int mDischargeScreenOffUnplugLevel;
277 int mDischargeAmountScreenOn;
278 int mDischargeAmountScreenOnSinceCharge;
279 int mDischargeAmountScreenOff;
280 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700283
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700284 // Mobile data transferred while on battery
285 private long[] mMobileDataTx = new long[4];
286 private long[] mMobileDataRx = new long[4];
287 private long[] mTotalDataTx = new long[4];
288 private long[] mTotalDataRx = new long[4];
289
290 private long mRadioDataUptime;
291 private long mRadioDataStart;
292
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700293 private int mBluetoothPingCount;
294 private int mBluetoothPingStart = -1;
295
Amith Yamasanif37447b2009-10-08 18:28:01 -0700296 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800297 private int mPhoneServiceStateRaw = -1;
298 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700299
Evan Millarc64edde2009-04-18 12:26:32 -0700300 /*
301 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
302 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700303 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700304 new HashMap<String, SamplingTimer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700305
Evan Millarc64edde2009-04-18 12:26:32 -0700306 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
307 return mKernelWakelockStats;
308 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700309
Evan Millarc64edde2009-04-18 12:26:32 -0700310 private static int sKernelWakelockUpdateVersion = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700311
Evan Millarc64edde2009-04-18 12:26:32 -0700312 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
313 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
314 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
315 Process.PROC_TAB_TERM,
316 Process.PROC_TAB_TERM,
317 Process.PROC_TAB_TERM,
318 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
319 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700320
Evan Millarc64edde2009-04-18 12:26:32 -0700321 private final String[] mProcWakelocksName = new String[3];
322 private final long[] mProcWakelocksData = new long[3];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700323
Evan Millarc64edde2009-04-18 12:26:32 -0700324 /*
325 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
326 * to mKernelWakelockStats.
327 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700328 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700329 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700331 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700332
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700333 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
334
335 /** Network ifaces that {@link ConnectivityManager} has claimed as mobile. */
336 private HashSet<String> mMobileIfaces = Sets.newHashSet();
337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 // For debugging
339 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700340 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700341 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 }
343
344 public static interface Unpluggable {
345 void unplug(long batteryUptime, long batteryRealtime);
346 void plug(long batteryUptime, long batteryRealtime);
347 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700350 * State for keeping track of counting information.
351 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700352 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700353 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700354 final ArrayList<Unpluggable> mUnpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700355 int mLoadedCount;
356 int mLastCount;
357 int mUnpluggedCount;
358 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700359
Dianne Hackborn617f8772009-03-31 15:04:46 -0700360 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700361 mUnpluggables = unpluggables;
Christopher Tate4cee7252010-03-19 14:50:40 -0700362 mPluggedCount = in.readInt();
363 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700364 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700365 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700366 mUnpluggedCount = in.readInt();
367 unpluggables.add(this);
368 }
369
370 Counter(ArrayList<Unpluggable> unpluggables) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700371 mUnpluggables = unpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700372 unpluggables.add(this);
373 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700374
Dianne Hackborn617f8772009-03-31 15:04:46 -0700375 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700376 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700377 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700378 out.writeInt(mUnpluggedCount);
379 }
380
381 public void unplug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700382 mUnpluggedCount = mPluggedCount;
383 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700384 }
385
386 public void plug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700387 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700388 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700389
Dianne Hackborn617f8772009-03-31 15:04:46 -0700390 /**
391 * Writes a possibly null Counter to a Parcel.
392 *
393 * @param out the Parcel to be written to.
394 * @param counter a Counter, or null.
395 */
396 public static void writeCounterToParcel(Parcel out, Counter counter) {
397 if (counter == null) {
398 out.writeInt(0); // indicates null
399 return;
400 }
401 out.writeInt(1); // indicates non-null
402
403 counter.writeToParcel(out);
404 }
405
406 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700407 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700408 int val;
409 if (which == STATS_LAST) {
410 val = mLastCount;
411 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700412 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700413 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700414 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700415 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700416 val -= mLoadedCount;
417 }
418 }
419
420 return val;
421 }
422
423 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700424 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700425 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
426 + " mUnpluggedCount=" + mUnpluggedCount
427 + " mPluggedCount=" + mPluggedCount);
428 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700429
Christopher Tate4cee7252010-03-19 14:50:40 -0700430 void stepAtomic() {
431 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700432 }
433
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700434 /**
435 * Clear state of this counter.
436 */
437 void reset(boolean detachIfReset) {
438 mCount.set(0);
439 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
440 if (detachIfReset) {
441 detach();
442 }
443 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700444
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700445 void detach() {
446 mUnpluggables.remove(this);
447 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700448
Dianne Hackborn617f8772009-03-31 15:04:46 -0700449 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700450 int count = mCount.get();
451 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700452 }
453
454 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700455 mLoadedCount = in.readInt();
456 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700457 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700458 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700459 }
460 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700461
462 public static class SamplingCounter extends Counter {
463
464 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
465 super(unpluggables, in);
466 }
467
468 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
469 super(unpluggables);
470 }
471
Christopher Tate4cee7252010-03-19 14:50:40 -0700472 public void addCountAtomic(long count) {
473 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700474 }
475 }
476
Dianne Hackborn617f8772009-03-31 15:04:46 -0700477 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 * State for keeping track of timing information.
479 */
Evan Millarc64edde2009-04-18 12:26:32 -0700480 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 final int mType;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700482 final ArrayList<Unpluggable> mUnpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 int mCount;
485 int mLoadedCount;
486 int mLastCount;
487 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 // Times are in microseconds for better accuracy when dividing by the
490 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 /**
493 * The total time we have accumulated since the start of the original
494 * boot, to the last time something interesting happened in the
495 * current run.
496 */
497 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 /**
500 * The total time we loaded for the previous runs. Subtract this from
501 * mTotalTime to find the time for the current run of the system.
502 */
503 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 /**
506 * The run time of the last run of the system, as loaded from the
507 * saved data.
508 */
509 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 /**
512 * The value of mTotalTime when unplug() was last called. Subtract
513 * this from mTotalTime to find the time since the last unplug from
514 * power.
515 */
516 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700517
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700518 /**
519 * Constructs from a parcel.
520 * @param type
521 * @param unpluggables
522 * @param powerType
523 * @param in
524 */
Evan Millarc64edde2009-04-18 12:26:32 -0700525 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700527 mUnpluggables = unpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 mCount = in.readInt();
530 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700531 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 mUnpluggedCount = in.readInt();
533 mTotalTime = in.readLong();
534 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700535 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 mUnpluggedTime = in.readLong();
537 unpluggables.add(this);
538 }
539
Evan Millarc64edde2009-04-18 12:26:32 -0700540 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700542 mUnpluggables = unpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 unpluggables.add(this);
544 }
Evan Millarc64edde2009-04-18 12:26:32 -0700545
546 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700547
Evan Millarc64edde2009-04-18 12:26:32 -0700548 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700549
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700550 /**
551 * Clear state of this timer. Returns true if the timer is inactive
552 * so can be completely dropped.
553 */
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700554 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700555 mTotalTime = mLoadedTime = mLastTime = 0;
556 mCount = mLoadedCount = mLastCount = 0;
557 if (detachIfReset) {
558 detach();
559 }
560 return true;
561 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700562
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700563 void detach() {
564 mUnpluggables.remove(this);
565 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 public void writeToParcel(Parcel out, long batteryRealtime) {
568 out.writeInt(mCount);
569 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 out.writeInt(mUnpluggedCount);
571 out.writeLong(computeRunTimeLocked(batteryRealtime));
572 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573 out.writeLong(mUnpluggedTime);
574 }
575
576 public void unplug(long batteryUptime, long batteryRealtime) {
577 if (DEBUG && mType < 0) {
578 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
579 + " old mUnpluggedTime=" + mUnpluggedTime
580 + " old mUnpluggedCount=" + mUnpluggedCount);
581 }
582 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
583 mUnpluggedCount = mCount;
584 if (DEBUG && mType < 0) {
585 Log.v(TAG, "unplug #" + mType
586 + ": new mUnpluggedTime=" + mUnpluggedTime
587 + " new mUnpluggedCount=" + mUnpluggedCount);
588 }
589 }
590
591 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700592 if (DEBUG && mType < 0) {
593 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
594 + " old mTotalTime=" + mTotalTime);
595 }
596 mTotalTime = computeRunTimeLocked(batteryRealtime);
597 mCount = computeCurrentCountLocked();
598 if (DEBUG && mType < 0) {
599 Log.v(TAG, "plug #" + mType
600 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 }
602 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 /**
605 * Writes a possibly null Timer to a Parcel.
606 *
607 * @param out the Parcel to be written to.
608 * @param timer a Timer, or null.
609 */
610 public static void writeTimerToParcel(Parcel out, Timer timer,
611 long batteryRealtime) {
612 if (timer == null) {
613 out.writeInt(0); // indicates null
614 return;
615 }
616 out.writeInt(1); // indicates non-null
617
618 timer.writeToParcel(out, batteryRealtime);
619 }
620
621 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700622 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 long val;
624 if (which == STATS_LAST) {
625 val = mLastTime;
626 } else {
627 val = computeRunTimeLocked(batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700628 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 val -= mUnpluggedTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700630 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 val -= mLoadedTime;
632 }
633 }
634
635 return val;
636 }
637
638 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700639 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 int val;
641 if (which == STATS_LAST) {
642 val = mLastCount;
643 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700644 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700645 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800646 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700647 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 val -= mLoadedCount;
649 }
650 }
651
652 return val;
653 }
654
Dianne Hackborn627bba72009-03-24 22:32:56 -0700655 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700656 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800657 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
658 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700659 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800660 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700661 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800662 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700663 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700664
665
Evan Millarc64edde2009-04-18 12:26:32 -0700666 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
667 long runTime = computeRunTimeLocked(batteryRealtime);
668 // Divide by 1000 for backwards compatibility
669 out.writeLong((runTime + 500) / 1000);
Evan Millarc64edde2009-04-18 12:26:32 -0700670 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -0700671 }
672
673 void readSummaryFromParcelLocked(Parcel in) {
674 // Multiply by 1000 for backwards compatibility
675 mTotalTime = mLoadedTime = in.readLong() * 1000;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700676 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700677 mUnpluggedTime = mTotalTime;
678 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700679 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700680 mUnpluggedCount = mCount;
681 }
682 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700683
Evan Millarc64edde2009-04-18 12:26:32 -0700684 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700685
Evan Millarc64edde2009-04-18 12:26:32 -0700686 /**
687 * The most recent reported count from /proc/wakelocks.
688 */
689 int mCurrentReportedCount;
690
691 /**
692 * The reported count from /proc/wakelocks when unplug() was last
693 * called.
694 */
695 int mUnpluggedReportedCount;
696
697 /**
698 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700699 */
Evan Millarc64edde2009-04-18 12:26:32 -0700700 long mCurrentReportedTotalTime;
701
702
703 /**
704 * The reported total_time from /proc/wakelocks when unplug() was last
705 * called.
706 */
707 long mUnpluggedReportedTotalTime;
708
709 /**
710 * Whether we are currently in a discharge cycle.
711 */
712 boolean mInDischarge;
713
714 /**
715 * Whether we are currently recording reported values.
716 */
717 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700718
Evan Millarc64edde2009-04-18 12:26:32 -0700719 /*
720 * A sequnce counter, incremented once for each update of the stats.
721 */
722 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700723
Evan Millarc64edde2009-04-18 12:26:32 -0700724 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
725 super(0, unpluggables, in);
726 mCurrentReportedCount = in.readInt();
727 mUnpluggedReportedCount = in.readInt();
728 mCurrentReportedTotalTime = in.readLong();
729 mUnpluggedReportedTotalTime = in.readLong();
730 mTrackingReportedValues = in.readInt() == 1;
731 mInDischarge = inDischarge;
732 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700733
734 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
Evan Millarc64edde2009-04-18 12:26:32 -0700735 boolean trackReportedValues) {
736 super(0, unpluggables);
737 mTrackingReportedValues = trackReportedValues;
738 mInDischarge = inDischarge;
739 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700740
Evan Millarc64edde2009-04-18 12:26:32 -0700741 public void setStale() {
742 mTrackingReportedValues = false;
743 mUnpluggedReportedTotalTime = 0;
744 mUnpluggedReportedCount = 0;
745 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700746
Evan Millarc64edde2009-04-18 12:26:32 -0700747 public void setUpdateVersion(int version) {
748 mUpdateVersion = version;
749 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700750
Evan Millarc64edde2009-04-18 12:26:32 -0700751 public int getUpdateVersion() {
752 return mUpdateVersion;
753 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700754
Evan Millarc64edde2009-04-18 12:26:32 -0700755 public void updateCurrentReportedCount(int count) {
756 if (mInDischarge && mUnpluggedReportedCount == 0) {
757 // Updating the reported value for the first time.
758 mUnpluggedReportedCount = count;
759 // If we are receiving an update update mTrackingReportedValues;
760 mTrackingReportedValues = true;
761 }
762 mCurrentReportedCount = count;
763 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700764
Evan Millarc64edde2009-04-18 12:26:32 -0700765 public void updateCurrentReportedTotalTime(long totalTime) {
766 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
767 // Updating the reported value for the first time.
768 mUnpluggedReportedTotalTime = totalTime;
769 // If we are receiving an update update mTrackingReportedValues;
770 mTrackingReportedValues = true;
771 }
772 mCurrentReportedTotalTime = totalTime;
773 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700774
Evan Millarc64edde2009-04-18 12:26:32 -0700775 public void unplug(long batteryUptime, long batteryRealtime) {
776 super.unplug(batteryUptime, batteryRealtime);
777 if (mTrackingReportedValues) {
778 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
779 mUnpluggedReportedCount = mCurrentReportedCount;
780 }
781 mInDischarge = true;
782 }
783
784 public void plug(long batteryUptime, long batteryRealtime) {
785 super.plug(batteryUptime, batteryRealtime);
786 mInDischarge = false;
787 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700788
Evan Millarc64edde2009-04-18 12:26:32 -0700789 public void logState(Printer pw, String prefix) {
790 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700791 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -0700792 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
793 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
794 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
795 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700796
Evan Millarc64edde2009-04-18 12:26:32 -0700797 protected long computeRunTimeLocked(long curBatteryRealtime) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700798 return mTotalTime + (mInDischarge && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -0700799 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
800 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700801
Evan Millarc64edde2009-04-18 12:26:32 -0700802 protected int computeCurrentCountLocked() {
803 return mCount + (mInDischarge && mTrackingReportedValues
804 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
805 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700806
Evan Millarc64edde2009-04-18 12:26:32 -0700807 public void writeToParcel(Parcel out, long batteryRealtime) {
808 super.writeToParcel(out, batteryRealtime);
809 out.writeInt(mCurrentReportedCount);
810 out.writeInt(mUnpluggedReportedCount);
811 out.writeLong(mCurrentReportedTotalTime);
812 out.writeLong(mUnpluggedReportedTotalTime);
813 out.writeInt(mTrackingReportedValues ? 1 : 0);
814 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700815
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700816 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
817 super.reset(stats, detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700818 setStale();
819 return true;
820 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700821
Evan Millarc64edde2009-04-18 12:26:32 -0700822 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
823 super.writeSummaryFromParcelLocked(out, batteryRealtime);
824 out.writeLong(mCurrentReportedTotalTime);
825 out.writeInt(mCurrentReportedCount);
826 out.writeInt(mTrackingReportedValues ? 1 : 0);
827 }
828
829 void readSummaryFromParcelLocked(Parcel in) {
830 super.readSummaryFromParcelLocked(in);
831 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
832 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
833 mTrackingReportedValues = in.readInt() == 1;
834 }
835 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700836
Evan Millarc64edde2009-04-18 12:26:32 -0700837 /**
838 * State for keeping track of timing information.
839 */
840 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700841 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -0700842 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700843
Evan Millarc64edde2009-04-18 12:26:32 -0700844 int mNesting;
845
Evan Millarc64edde2009-04-18 12:26:32 -0700846 /**
847 * The last time at which we updated the timer. If mNesting is > 0,
848 * subtract this from the current battery time to find the amount of
849 * time we have been running since we last computed an update.
850 */
851 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700852
Evan Millarc64edde2009-04-18 12:26:32 -0700853 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700854 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -0700855 * was actually held for an interesting duration.
856 */
857 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700858
Amith Yamasanif37447b2009-10-08 18:28:01 -0700859 long mTimeout;
860
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700861 /**
862 * For partial wake locks, keep track of whether we are in the list
863 * to consume CPU cycles.
864 */
865 boolean mInList;
866
867 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700868 ArrayList<Unpluggable> unpluggables, Parcel in) {
869 super(type, unpluggables, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700870 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700871 mTimerPool = timerPool;
872 mUpdateTime = in.readLong();
873 }
874
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700875 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -0700876 ArrayList<Unpluggable> unpluggables) {
877 super(type, unpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700878 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -0700879 mTimerPool = timerPool;
880 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700881
Amith Yamasanif37447b2009-10-08 18:28:01 -0700882 void setTimeout(long timeout) {
883 mTimeout = timeout;
884 }
885
Evan Millarc64edde2009-04-18 12:26:32 -0700886 public void writeToParcel(Parcel out, long batteryRealtime) {
887 super.writeToParcel(out, batteryRealtime);
888 out.writeLong(mUpdateTime);
889 }
890
891 public void plug(long batteryUptime, long batteryRealtime) {
892 if (mNesting > 0) {
893 if (DEBUG && mType < 0) {
894 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
895 }
896 super.plug(batteryUptime, batteryRealtime);
897 mUpdateTime = batteryRealtime;
898 if (DEBUG && mType < 0) {
899 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
900 }
901 }
902 }
903
904 public void logState(Printer pw, String prefix) {
905 super.logState(pw, prefix);
906 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 + " mAcquireTime=" + mAcquireTime);
908 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 void startRunningLocked(BatteryStatsImpl stats) {
911 if (mNesting++ == 0) {
912 mUpdateTime = stats.getBatteryRealtimeLocked(
913 SystemClock.elapsedRealtime() * 1000);
914 if (mTimerPool != null) {
915 // Accumulate time to all currently active timers before adding
916 // this new one to the pool.
917 refreshTimersLocked(stats, mTimerPool);
918 // Add this timer to the active pool
919 mTimerPool.add(this);
920 }
921 // Increment the count
922 mCount++;
923 mAcquireTime = mTotalTime;
924 if (DEBUG && mType < 0) {
925 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
926 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
927 + " mAcquireTime=" + mAcquireTime);
928 }
929 }
930 }
931
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700932 boolean isRunningLocked() {
933 return mNesting > 0;
934 }
935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 void stopRunningLocked(BatteryStatsImpl stats) {
937 // Ignore attempt to stop a timer that isn't running
938 if (mNesting == 0) {
939 return;
940 }
941 if (--mNesting == 0) {
942 if (mTimerPool != null) {
943 // Accumulate time to all active counters, scaled by the total
944 // active in the pool, before taking this one out of the pool.
945 refreshTimersLocked(stats, mTimerPool);
946 // Remove this timer from the active pool
947 mTimerPool.remove(this);
948 } else {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700949 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
951 mNesting = 1;
952 mTotalTime = computeRunTimeLocked(batteryRealtime);
953 mNesting = 0;
954 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 if (DEBUG && mType < 0) {
957 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
958 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
959 + " mAcquireTime=" + mAcquireTime);
960 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 if (mTotalTime == mAcquireTime) {
963 // If there was no change in the time, then discard this
964 // count. A somewhat cheezy strategy, but hey.
965 mCount--;
966 }
967 }
968 }
969
970 // Update the total time for all other running Timers with the same type as this Timer
971 // due to a change in timer count
972 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700973 final ArrayList<StopwatchTimer> pool) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700974 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
976 final int N = pool.size();
977 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700978 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979 long heldTime = batteryRealtime - t.mUpdateTime;
980 if (heldTime > 0) {
981 t.mTotalTime += heldTime / N;
982 }
983 t.mUpdateTime = batteryRealtime;
984 }
985 }
986
Evan Millarc64edde2009-04-18 12:26:32 -0700987 @Override
988 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700989 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
990 curBatteryRealtime = mUpdateTime + mTimeout;
991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 return mTotalTime + (mNesting > 0
993 ? (curBatteryRealtime - mUpdateTime)
994 / (mTimerPool != null ? mTimerPool.size() : 1)
995 : 0);
996 }
997
Evan Millarc64edde2009-04-18 12:26:32 -0700998 @Override
999 protected int computeCurrentCountLocked() {
1000 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 }
1002
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001003 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001004 boolean canDetach = mNesting <= 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001005 super.reset(stats, canDetach && detachIfReset);
1006 if (mNesting > 0) {
1007 mUpdateTime = stats.getBatteryRealtimeLocked(
1008 SystemClock.elapsedRealtime() * 1000);
1009 }
1010 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001011 return canDetach;
1012 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001013
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001014 void detach() {
1015 super.detach();
1016 if (mTimerPool != null) {
1017 mTimerPool.remove(this);
1018 }
1019 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001022 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 mNesting = 0;
1024 }
1025 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001026
Evan Millarc64edde2009-04-18 12:26:32 -07001027 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001028
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001029 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -07001030 int len;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001031
Evan Millarc64edde2009-04-18 12:26:32 -07001032 try {
1033 FileInputStream is = new FileInputStream("/proc/wakelocks");
1034 len = is.read(buffer);
1035 is.close();
1036
1037 if (len > 0) {
1038 int i;
1039 for (i=0; i<len; i++) {
1040 if (buffer[i] == '\0') {
1041 len = i;
1042 break;
1043 }
1044 }
1045 }
1046 } catch (java.io.FileNotFoundException e) {
1047 return null;
1048 } catch (java.io.IOException e) {
1049 return null;
1050 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001051
Evan Millarc64edde2009-04-18 12:26:32 -07001052 return parseProcWakelocks(buffer, len);
1053 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001054
Evan Millarc64edde2009-04-18 12:26:32 -07001055 private final Map<String, KernelWakelockStats> parseProcWakelocks(
1056 byte[] wlBuffer, int len) {
1057 String name;
1058 int count;
1059 long totalTime;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001060 int startIndex;
1061 int endIndex;
Evan Millarc64edde2009-04-18 12:26:32 -07001062 int numUpdatedWlNames = 0;
1063
1064 // Advance past the first line.
1065 int i;
1066 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1067 startIndex = endIndex = i + 1;
1068
1069 synchronized(this) {
1070 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001071
Evan Millarc64edde2009-04-18 12:26:32 -07001072 sKernelWakelockUpdateVersion++;
1073 while (endIndex < len) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001074 for (endIndex=startIndex;
1075 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
Evan Millarc64edde2009-04-18 12:26:32 -07001076 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001077 endIndex++; // endIndex is an exclusive upper bound.
1078 // Don't go over the end of the buffer, Process.parseProcLine might
1079 // write to wlBuffer[endIndex]
1080 if (endIndex >= (len - 1) ) {
1081 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -07001082 }
Evan Millarc64edde2009-04-18 12:26:32 -07001083
1084 String[] nameStringArray = mProcWakelocksName;
1085 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001086 // Stomp out any bad characters since this is from a circular buffer
1087 // A corruption is seen sometimes that results in the vm crashing
1088 // This should prevent crashes and the line will probably fail to parse
1089 for (int j = startIndex; j < endIndex; j++) {
1090 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1091 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001092 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
1093 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001094
Evan Millarc64edde2009-04-18 12:26:32 -07001095 name = nameStringArray[0];
1096 count = (int) wlData[1];
1097 // convert nanoseconds to microseconds with rounding.
1098 totalTime = (wlData[2] + 500) / 1000;
1099
Amith Yamasani53b707b2009-09-30 11:05:30 -07001100 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001101 if (!m.containsKey(name)) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001102 m.put(name, new KernelWakelockStats(count, totalTime,
Evan Millarc64edde2009-04-18 12:26:32 -07001103 sKernelWakelockUpdateVersion));
1104 numUpdatedWlNames++;
1105 } else {
1106 KernelWakelockStats kwlStats = m.get(name);
1107 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1108 kwlStats.mCount += count;
1109 kwlStats.mTotalTime += totalTime;
1110 } else {
1111 kwlStats.mCount = count;
1112 kwlStats.mTotalTime = totalTime;
1113 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1114 numUpdatedWlNames++;
1115 }
1116 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001117 }
Evan Millarc64edde2009-04-18 12:26:32 -07001118 startIndex = endIndex;
1119 }
1120
1121 if (m.size() != numUpdatedWlNames) {
1122 // Don't report old data.
1123 Iterator<KernelWakelockStats> itr = m.values().iterator();
1124 while (itr.hasNext()) {
1125 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1126 itr.remove();
1127 }
1128 }
1129 }
1130 return m;
1131 }
1132 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001133
Evan Millarc64edde2009-04-18 12:26:32 -07001134 private class KernelWakelockStats {
1135 public int mCount;
1136 public long mTotalTime;
1137 public int mVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001138
Evan Millarc64edde2009-04-18 12:26:32 -07001139 KernelWakelockStats(int count, long totalTime, int version) {
1140 mCount = count;
1141 mTotalTime = totalTime;
1142 mVersion = version;
1143 }
1144 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001145
Evan Millarc64edde2009-04-18 12:26:32 -07001146 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001147 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001148 * doesn't already exist.
1149 */
1150 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1151 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1152 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001153 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07001154 true /* track reported values */);
1155 mKernelWakelockStats.put(name, kwlt);
1156 }
1157 return kwlt;
1158 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001159
1160 private void doDataPlug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001161 dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED];
1162 dataTransfer[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001163 }
1164
1165 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001166 dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001167 }
1168
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001169 /**
1170 * Radio uptime in microseconds when transferring data. This value is very approximate.
1171 * @return
1172 */
1173 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001174 try {
1175 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
1176 if (!awakeTimeFile.exists()) return 0;
1177 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
1178 String line = br.readLine();
1179 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001180 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001181 } catch (NumberFormatException nfe) {
1182 // Nothing
1183 } catch (IOException ioe) {
1184 // Nothing
1185 }
1186 return 0;
1187 }
1188
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001189 /**
1190 * @deprecated use getRadioDataUptime
1191 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001192 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001193 return getRadioDataUptime() / 1000;
1194 }
1195
1196 /**
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001197 * Returns the duration that the cell radio was up for data transfers.
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001198 */
1199 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001200 if (mRadioDataStart == -1) {
1201 return mRadioDataUptime;
1202 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001203 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001204 }
1205 }
1206
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001207 private int getCurrentBluetoothPingCount() {
1208 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001209 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1210 if (deviceList.size() > 0) {
1211 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001212 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001213 }
1214 return -1;
1215 }
1216
1217 public int getBluetoothPingCount() {
1218 if (mBluetoothPingStart == -1) {
1219 return mBluetoothPingCount;
1220 } else if (mBtHeadset != null) {
1221 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1222 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001223 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001224 }
1225
1226 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001227 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1228 mBluetoothPingStart = getCurrentBluetoothPingCount();
1229 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001230 mBtHeadset = headset;
1231 }
1232
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001233 int mChangedBufferStates = 0;
1234
1235 void addHistoryBufferLocked(long curTime) {
1236 if (!mHaveBatteryLevel || !mRecordingHistory) {
1237 return;
1238 }
1239
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001240 final long timeDiff = (mHistoryBaseTime+curTime) - mHistoryLastWritten.time;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001241 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001242 && timeDiff < 2000
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001243 && ((mHistoryLastWritten.states^mHistoryCur.states)&mChangedBufferStates) == 0) {
1244 // If the current is the same as the one before, then we no
1245 // longer need the entry.
1246 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
1247 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
1248 mHistoryBufferLastPos = -1;
1249 if (mHistoryLastLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001250 && timeDiff < 500 && mHistoryLastLastWritten.same(mHistoryCur)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001251 // If this results in us returning to the state written
1252 // prior to the last one, then we can just delete the last
1253 // written one and drop the new one. Nothing more to do.
1254 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
1255 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1256 return;
1257 }
1258 mChangedBufferStates |= mHistoryLastWritten.states^mHistoryCur.states;
1259 curTime = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001260 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001261 } else {
1262 mChangedBufferStates = 0;
1263 }
1264
1265 final int dataSize = mHistoryBuffer.dataSize();
1266 if (dataSize >= MAX_HISTORY_BUFFER) {
1267 if (!mHistoryOverflow) {
1268 mHistoryOverflow = true;
1269 addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW);
1270 }
1271
1272 // Once we've reached the maximum number of items, we only
1273 // record changes to the battery level and the most interesting states.
1274 // Once we've reached the maximum maximum number of items, we only
1275 // record changes to the battery level.
1276 if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
1277 (dataSize >= MAX_MAX_HISTORY_BUFFER
1278 || ((mHistoryEnd.states^mHistoryCur.states)
1279 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
1280 return;
1281 }
1282 }
1283
1284 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE);
1285 }
1286
1287 void addHistoryBufferLocked(long curTime, byte cmd) {
1288 int origPos = 0;
1289 if (mIteratingHistory) {
1290 origPos = mHistoryBuffer.dataPosition();
1291 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
1292 }
1293 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
1294 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
1295 mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
1296 mHistoryLastWritten.writeDelta(mHistoryBuffer, mHistoryLastLastWritten);
1297 mLastHistoryTime = curTime;
1298 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
1299 + " now " + mHistoryBuffer.dataPosition()
1300 + " size is now " + mHistoryBuffer.dataSize());
1301 if (mIteratingHistory) {
1302 mHistoryBuffer.setDataPosition(origPos);
1303 }
1304 }
1305
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001306 int mChangedStates = 0;
1307
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001308 void addHistoryRecordLocked(long curTime) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001309 addHistoryBufferLocked(curTime);
1310
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001311 if (!USE_OLD_HISTORY) {
1312 return;
1313 }
1314
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001315 if (!mHaveBatteryLevel || !mRecordingHistory) {
1316 return;
1317 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001318
1319 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001320 // and no states have since the last recorded entry changed and
1321 // are now resetting back to their original value, then just collapse
1322 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001323 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001324 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000)
1325 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001326 // If the current is the same as the one before, then we no
1327 // longer need the entry.
1328 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001329 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500)
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001330 && mHistoryLastEnd.same(mHistoryCur)) {
1331 mHistoryLastEnd.next = null;
1332 mHistoryEnd.next = mHistoryCache;
1333 mHistoryCache = mHistoryEnd;
1334 mHistoryEnd = mHistoryLastEnd;
1335 mHistoryLastEnd = null;
1336 } else {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001337 mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001338 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
1339 }
1340 return;
1341 }
1342
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001343 mChangedStates = 0;
1344
1345 if (mNumHistoryItems == MAX_HISTORY_ITEMS
1346 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001347 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
1348 }
1349
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001350 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
1351 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001352 // record changes to the battery level and the most interesting states.
1353 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001354 // record changes to the battery level.
1355 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001356 == mHistoryCur.batteryLevel &&
1357 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
1358 || ((mHistoryEnd.states^mHistoryCur.states)
1359 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001360 return;
1361 }
1362 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001363
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001364 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
1365 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001366
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001367 void addHistoryRecordLocked(long curTime, byte cmd) {
1368 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001369 if (rec != null) {
1370 mHistoryCache = rec.next;
1371 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001372 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001373 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001374 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001375
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001376 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001377 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001378
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001379 void addHistoryRecordLocked(HistoryItem rec) {
1380 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001381 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001382 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001383 if (mHistoryEnd != null) {
1384 mHistoryEnd.next = rec;
1385 mHistoryEnd = rec;
1386 } else {
1387 mHistory = mHistoryEnd = rec;
1388 }
1389 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001390
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001391 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001392 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001393 if (USE_OLD_HISTORY) {
1394 if (mHistory != null) {
1395 mHistoryEnd.next = mHistoryCache;
1396 mHistoryCache = mHistory;
1397 mHistory = mHistoryLastEnd = mHistoryEnd = null;
1398 }
1399 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001400 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001401
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001402 mHistoryBaseTime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001403 mLastHistoryTime = 0;
1404
1405 mHistoryBuffer.setDataSize(0);
1406 mHistoryBuffer.setDataPosition(0);
1407 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER/2);
1408 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1409 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
1410 mHistoryBufferLastPos = -1;
1411 mHistoryOverflow = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001412 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001413
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001414 public void doUnplugLocked(long batteryUptime, long batteryRealtime) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001415 NetworkStats.Entry entry = null;
1416
1417 // Track UID data usage
1418 final NetworkStats uidStats = getNetworkStatsDetailGroupedByUid();
1419 final int size = uidStats.size();
1420 for (int i = 0; i < size; i++) {
1421 entry = uidStats.getValues(i, entry);
1422
1423 final Uid u = mUidStats.get(entry.uid);
1424 if (u == null) continue;
1425
1426 u.mStartedTcpBytesReceived = entry.rxBytes;
1427 u.mStartedTcpBytesSent = entry.txBytes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1429 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1430 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1433 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
1434 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001435
1436 // Track both mobile and total overall data
1437 final NetworkStats ifaceStats = getNetworkStatsSummary();
1438 entry = ifaceStats.getTotal(entry, mMobileIfaces);
1439 doDataUnplug(mMobileDataRx, entry.rxBytes);
1440 doDataUnplug(mMobileDataTx, entry.txBytes);
1441 entry = ifaceStats.getTotal(entry);
1442 doDataUnplug(mTotalDataRx, entry.rxBytes);
1443 doDataUnplug(mTotalDataTx, entry.txBytes);
1444
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001445 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001446 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001447 mRadioDataUptime = 0;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001448
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001449 // Track bt headset ping count
1450 mBluetoothPingStart = getCurrentBluetoothPingCount();
1451 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001453
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001454 public void doPlugLocked(long batteryUptime, long batteryRealtime) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001455 NetworkStats.Entry entry = null;
1456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001457 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1458 Uid u = mUidStats.valueAt(iu);
1459 if (u.mStartedTcpBytesReceived >= 0) {
1460 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1461 u.mStartedTcpBytesReceived = -1;
1462 }
1463 if (u.mStartedTcpBytesSent >= 0) {
1464 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1465 u.mStartedTcpBytesSent = -1;
1466 }
1467 }
1468 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1469 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
1470 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001471
1472 // Track both mobile and total overall data
1473 final NetworkStats ifaceStats = getNetworkStatsSummary();
1474 entry = ifaceStats.getTotal(entry, mMobileIfaces);
1475 doDataPlug(mMobileDataRx, entry.rxBytes);
1476 doDataPlug(mMobileDataTx, entry.txBytes);
1477 entry = ifaceStats.getTotal(entry);
1478 doDataPlug(mTotalDataRx, entry.rxBytes);
1479 doDataPlug(mTotalDataTx, entry.txBytes);
1480
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001481 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001482 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001483 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001484
1485 // Track bt headset ping count
1486 mBluetoothPingCount = getBluetoothPingCount();
1487 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001489
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001490 int mWakeLockNesting;
1491
1492 public void noteStartWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001493 if (type == WAKE_TYPE_PARTIAL) {
1494 // Only care about partial wake locks, since full wake locks
1495 // will be canceled when the user puts the screen to sleep.
1496 if (mWakeLockNesting == 0) {
1497 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
1498 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
1499 + Integer.toHexString(mHistoryCur.states));
1500 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1501 }
1502 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001503 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001504 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001505 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1506 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1507 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1508 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001509 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
1510 }
1511 }
1512
1513 public void noteStopWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001514 if (type == WAKE_TYPE_PARTIAL) {
1515 mWakeLockNesting--;
1516 if (mWakeLockNesting == 0) {
1517 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
1518 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
1519 + Integer.toHexString(mHistoryCur.states));
1520 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1521 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001522 }
1523 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001524 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1525 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1526 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1527 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001528 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
1529 }
1530 }
1531
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001532 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1533 int N = ws.size();
1534 for (int i=0; i<N; i++) {
1535 noteStartWakeLocked(ws.get(i), pid, name, type);
1536 }
1537 }
1538
1539 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1540 int N = ws.size();
1541 for (int i=0; i<N; i++) {
1542 noteStopWakeLocked(ws.get(i), pid, name, type);
1543 }
1544 }
1545
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001546 public int startAddingCpuLocked() {
1547 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
1548
1549 if (mScreenOn) {
1550 return 0;
1551 }
1552
1553 final int N = mPartialTimers.size();
1554 if (N == 0) {
1555 mLastPartialTimers.clear();
1556 return 0;
1557 }
1558
1559 // How many timers should consume CPU? Only want to include ones
1560 // that have already been in the list.
1561 for (int i=0; i<N; i++) {
1562 StopwatchTimer st = mPartialTimers.get(i);
1563 if (st.mInList) {
1564 Uid uid = st.mUid;
1565 // We don't include the system UID, because it so often
1566 // holds wake locks at one request or another of an app.
1567 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1568 return 50;
1569 }
1570 }
1571 }
1572
1573 return 0;
1574 }
1575
1576 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
1577 final int N = mPartialTimers.size();
1578 if (perc != 0) {
1579 int num = 0;
1580 for (int i=0; i<N; i++) {
1581 StopwatchTimer st = mPartialTimers.get(i);
1582 if (st.mInList) {
1583 Uid uid = st.mUid;
1584 // We don't include the system UID, because it so often
1585 // holds wake locks at one request or another of an app.
1586 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1587 num++;
1588 }
1589 }
1590 }
1591 if (num != 0) {
1592 for (int i=0; i<N; i++) {
1593 StopwatchTimer st = mPartialTimers.get(i);
1594 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001595 Uid uid = st.mUid;
1596 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07001597 int myUTime = utime/num;
1598 int mySTime = stime/num;
1599 utime -= myUTime;
1600 stime -= mySTime;
1601 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001602 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
1603 proc.addCpuTimeLocked(myUTime, mySTime);
1604 proc.addSpeedStepTimes(cpuSpeedTimes);
1605 }
1606 }
1607 }
1608 }
1609
1610 // Just in case, collect any lost CPU time.
1611 if (utime != 0 || stime != 0) {
1612 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
1613 if (uid != null) {
1614 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
1615 proc.addCpuTimeLocked(utime, stime);
1616 proc.addSpeedStepTimes(cpuSpeedTimes);
1617 }
1618 }
1619 }
1620
1621 final int NL = mLastPartialTimers.size();
1622 boolean diff = N != NL;
1623 for (int i=0; i<NL && !diff; i++) {
1624 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
1625 }
1626 if (!diff) {
1627 for (int i=0; i<NL; i++) {
1628 mPartialTimers.get(i).mInList = true;
1629 }
1630 return;
1631 }
1632
1633 for (int i=0; i<NL; i++) {
1634 mLastPartialTimers.get(i).mInList = false;
1635 }
1636 mLastPartialTimers.clear();
1637 for (int i=0; i<N; i++) {
1638 StopwatchTimer st = mPartialTimers.get(i);
1639 st.mInList = true;
1640 mLastPartialTimers.add(st);
1641 }
1642 }
1643
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001644 public void noteProcessDiedLocked(int uid, int pid) {
1645 Uid u = mUidStats.get(uid);
1646 if (u != null) {
1647 u.mPids.remove(pid);
1648 }
1649 }
1650
1651 public long getProcessWakeTime(int uid, int pid, long realtime) {
1652 Uid u = mUidStats.get(uid);
1653 if (u != null) {
1654 Uid.Pid p = u.mPids.get(pid);
1655 if (p != null) {
1656 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
1657 }
1658 }
1659 return 0;
1660 }
1661
1662 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
1663 Uid u = mUidStats.get(uid);
1664 if (u != null) {
1665 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
1666 }
1667 }
1668
Dianne Hackborn287952c2010-09-22 22:34:31 -07001669 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
1670 Uid u = mUidStats.get(uid);
1671 if (u != null) {
1672 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
1673 }
1674 }
1675
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001676 int mSensorNesting;
1677
1678 public void noteStartSensorLocked(int uid, int sensor) {
1679 if (mSensorNesting == 0) {
1680 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
1681 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
1682 + Integer.toHexString(mHistoryCur.states));
1683 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1684 }
1685 mSensorNesting++;
1686 getUidStatsLocked(uid).noteStartSensor(sensor);
1687 }
1688
1689 public void noteStopSensorLocked(int uid, int sensor) {
1690 mSensorNesting--;
1691 if (mSensorNesting == 0) {
1692 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
1693 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
1694 + Integer.toHexString(mHistoryCur.states));
1695 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1696 }
1697 getUidStatsLocked(uid).noteStopSensor(sensor);
1698 }
1699
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001700 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001701
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001702 public void noteStartGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001703 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001704 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001705 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
1706 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001707 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001708 }
1709 mGpsNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001710 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001712
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001713 public void noteStopGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001714 mGpsNesting--;
1715 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001716 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001717 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
1718 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001719 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001720 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001721 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001724 public void noteScreenOnLocked() {
1725 if (!mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001726 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001727 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
1728 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001729 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 mScreenOn = true;
1731 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001732 if (mScreenBrightnessBin >= 0) {
1733 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1734 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001735
1736 // Fake a wake lock, so we consider the device waked as long
1737 // as the screen is on.
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001738 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001739
1740 // Update discharge amounts.
1741 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001742 updateDischargeScreenLevelsLocked(false, true);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001744 }
1745 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747 public void noteScreenOffLocked() {
1748 if (mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001749 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001750 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
1751 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001752 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001753 mScreenOn = false;
1754 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001755 if (mScreenBrightnessBin >= 0) {
1756 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1757 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001758
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001759 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001760
1761 // Update discharge amounts.
1762 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001763 updateDischargeScreenLevelsLocked(true, false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001764 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001765 }
1766 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001767
Dianne Hackborn617f8772009-03-31 15:04:46 -07001768 public void noteScreenBrightnessLocked(int brightness) {
1769 // Bin the brightness.
1770 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1771 if (bin < 0) bin = 0;
1772 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1773 if (mScreenBrightnessBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001774 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
1775 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001776 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
1777 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001778 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001779 if (mScreenOn) {
1780 if (mScreenBrightnessBin >= 0) {
1781 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1782 }
1783 mScreenBrightnessTimer[bin].startRunningLocked(this);
1784 }
1785 mScreenBrightnessBin = bin;
1786 }
1787 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001788
Christopher Tate4cee7252010-03-19 14:50:40 -07001789 public void noteInputEventAtomic() {
1790 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001791 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001792
Dianne Hackborn617f8772009-03-31 15:04:46 -07001793 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001794 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001795 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001797 public void notePhoneOnLocked() {
1798 if (!mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001799 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001800 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
1801 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001802 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 mPhoneOn = true;
1804 mPhoneOnTimer.startRunningLocked(this);
1805 }
1806 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 public void notePhoneOffLocked() {
1809 if (mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001810 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001811 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
1812 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001813 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001814 mPhoneOn = false;
1815 mPhoneOnTimer.stopRunningLocked(this);
1816 }
1817 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001818
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001819 void stopAllSignalStrengthTimersLocked(int except) {
Wink Saville52840902011-02-18 12:40:47 -08001820 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001821 if (i == except) {
1822 continue;
1823 }
1824 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1825 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
1826 }
1827 }
1828 }
1829
Dianne Hackborne4a59512010-12-07 11:08:07 -08001830 private int fixPhoneServiceState(int state, int signalBin) {
1831 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
1832 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1833 // to infer that we are scanning from other data.
1834 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08001835 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001836 state = ServiceState.STATE_IN_SERVICE;
1837 }
1838 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001839
Dianne Hackborne4a59512010-12-07 11:08:07 -08001840 return state;
1841 }
1842
1843 private void updateAllPhoneStateLocked(int state, int simState, int bin) {
1844 boolean scanning = false;
1845 boolean newHistory = false;
1846
1847 mPhoneServiceStateRaw = state;
1848 mPhoneSimStateRaw = simState;
1849 mPhoneSignalStrengthBinRaw = bin;
1850
1851 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
1852 // In this case we will always be STATE_OUT_OF_SERVICE, so need
1853 // to infer that we are scanning from other data.
1854 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08001855 && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001856 state = ServiceState.STATE_IN_SERVICE;
1857 }
1858 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001859
1860 // If the phone is powered off, stop all timers.
1861 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001862 bin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001863
Dianne Hackborne4a59512010-12-07 11:08:07 -08001864 // If we are in service, make sure the correct signal string timer is running.
1865 } else if (state == ServiceState.STATE_IN_SERVICE) {
1866 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001867
1868 // If we're out of service, we are in the lowest signal strength
1869 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07001870 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001871 scanning = true;
Wink Saville52840902011-02-18 12:40:47 -08001872 bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001873 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001874 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001875 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001876 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
1877 + Integer.toHexString(mHistoryCur.states));
Amith Yamasanif37447b2009-10-08 18:28:01 -07001878 mPhoneSignalScanningTimer.startRunningLocked(this);
1879 }
1880 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001881
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001882 if (!scanning) {
1883 // If we are no longer scanning, then stop the scanning timer.
1884 if (mPhoneSignalScanningTimer.isRunningLocked()) {
1885 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
1886 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
1887 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001888 newHistory = true;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001889 mPhoneSignalScanningTimer.stopRunningLocked(this);
1890 }
1891 }
1892
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001893 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001894 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
1895 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08001896 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001897 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08001898 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001899 mPhoneServiceState = state;
1900 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001901
1902 if (mPhoneSignalStrengthBin != bin) {
1903 if (mPhoneSignalStrengthBin >= 0) {
1904 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1905 }
1906 if (bin >= 0) {
1907 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1908 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1909 }
1910 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
1911 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
1912 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
1913 + Integer.toHexString(mHistoryCur.states));
1914 newHistory = true;
1915 } else {
1916 stopAllSignalStrengthTimersLocked(-1);
1917 }
1918 mPhoneSignalStrengthBin = bin;
1919 }
1920
1921 if (newHistory) {
1922 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1923 }
1924 }
1925
1926 /**
1927 * Telephony stack updates the phone state.
1928 * @param state phone state from ServiceState.getState()
1929 */
1930 public void notePhoneStateLocked(int state, int simState) {
1931 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001932 }
1933
Wink Savillee9b06d72009-05-18 21:47:50 -07001934 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001935 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08001936 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08001937 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001938 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001939
Dianne Hackborn627bba72009-03-24 22:32:56 -07001940 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1941 int bin = DATA_CONNECTION_NONE;
1942 if (hasData) {
1943 switch (dataType) {
1944 case TelephonyManager.NETWORK_TYPE_EDGE:
1945 bin = DATA_CONNECTION_EDGE;
1946 break;
1947 case TelephonyManager.NETWORK_TYPE_GPRS:
1948 bin = DATA_CONNECTION_GPRS;
1949 break;
1950 case TelephonyManager.NETWORK_TYPE_UMTS:
1951 bin = DATA_CONNECTION_UMTS;
1952 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001953 case TelephonyManager.NETWORK_TYPE_CDMA:
1954 bin = DATA_CONNECTION_CDMA;
1955 break;
1956 case TelephonyManager.NETWORK_TYPE_EVDO_0:
1957 bin = DATA_CONNECTION_EVDO_0;
1958 break;
1959 case TelephonyManager.NETWORK_TYPE_EVDO_A:
1960 bin = DATA_CONNECTION_EVDO_A;
1961 break;
1962 case TelephonyManager.NETWORK_TYPE_1xRTT:
1963 bin = DATA_CONNECTION_1xRTT;
1964 break;
1965 case TelephonyManager.NETWORK_TYPE_HSDPA:
1966 bin = DATA_CONNECTION_HSDPA;
1967 break;
1968 case TelephonyManager.NETWORK_TYPE_HSUPA:
1969 bin = DATA_CONNECTION_HSUPA;
1970 break;
1971 case TelephonyManager.NETWORK_TYPE_HSPA:
1972 bin = DATA_CONNECTION_HSPA;
1973 break;
1974 case TelephonyManager.NETWORK_TYPE_IDEN:
1975 bin = DATA_CONNECTION_IDEN;
1976 break;
1977 case TelephonyManager.NETWORK_TYPE_EVDO_B:
1978 bin = DATA_CONNECTION_EVDO_B;
1979 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07001980 case TelephonyManager.NETWORK_TYPE_LTE:
1981 bin = DATA_CONNECTION_LTE;
1982 break;
1983 case TelephonyManager.NETWORK_TYPE_EHRPD:
1984 bin = DATA_CONNECTION_EHRPD;
1985 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001986 default:
1987 bin = DATA_CONNECTION_OTHER;
1988 break;
1989 }
1990 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001991 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001992 if (mPhoneDataConnectionType != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001993 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
1994 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001995 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
1996 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001997 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07001998 if (mPhoneDataConnectionType >= 0) {
1999 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
2000 }
2001 mPhoneDataConnectionType = bin;
2002 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
2003 }
2004 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002005
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002006 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002007 if (!mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002008 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002009 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
2010 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002011 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002012 mWifiOn = true;
2013 mWifiOnTimer.startRunningLocked(this);
2014 }
2015 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002016
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002017 public void noteWifiOffLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002018 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002019 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002020 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
2021 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002022 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002023 mWifiOn = false;
2024 mWifiOnTimer.stopRunningLocked(this);
2025 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002026 if (mWifiOnUid >= 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002027 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002028 mWifiOnUid = -1;
2029 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002030 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002031
2032 public void noteAudioOnLocked(int uid) {
2033 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002034 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002035 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
2036 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002037 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002038 mAudioOn = true;
2039 mAudioOnTimer.startRunningLocked(this);
2040 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002041 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002042 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002043
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002044 public void noteAudioOffLocked(int uid) {
2045 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002046 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002047 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
2048 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002049 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002050 mAudioOn = false;
2051 mAudioOnTimer.stopRunningLocked(this);
2052 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002053 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002054 }
2055
2056 public void noteVideoOnLocked(int uid) {
2057 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002058 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002059 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
2060 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002061 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002062 mVideoOn = true;
2063 mVideoOnTimer.startRunningLocked(this);
2064 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002065 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002066 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002067
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002068 public void noteVideoOffLocked(int uid) {
2069 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002070 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002071 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
2072 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002073 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002074 mVideoOn = false;
2075 mVideoOnTimer.stopRunningLocked(this);
2076 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002077 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002078 }
2079
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002080 public void noteWifiRunningLocked(WorkSource ws) {
2081 if (!mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002082 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002083 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
2084 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002085 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002086 mGlobalWifiRunning = true;
2087 mGlobalWifiRunningTimer.startRunningLocked(this);
2088 int N = ws.size();
2089 for (int i=0; i<N; i++) {
2090 getUidStatsLocked(ws.get(i)).noteWifiRunningLocked();
2091 }
2092 } else {
2093 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002094 }
2095 }
2096
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002097 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
2098 if (mGlobalWifiRunning) {
2099 int N = oldWs.size();
2100 for (int i=0; i<N; i++) {
2101 getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked();
2102 }
2103 N = newWs.size();
2104 for (int i=0; i<N; i++) {
2105 getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked();
2106 }
2107 } else {
2108 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
2109 }
2110 }
2111
2112 public void noteWifiStoppedLocked(WorkSource ws) {
2113 if (mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002114 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002115 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
2116 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002117 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002118 mGlobalWifiRunning = false;
2119 mGlobalWifiRunningTimer.stopRunningLocked(this);
2120 int N = ws.size();
2121 for (int i=0; i<N; i++) {
2122 getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked();
2123 }
2124 } else {
2125 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002126 }
2127 }
2128
The Android Open Source Project10592532009-03-18 17:39:46 -07002129 public void noteBluetoothOnLocked() {
2130 if (!mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002131 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002132 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
2133 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002134 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002135 mBluetoothOn = true;
2136 mBluetoothOnTimer.startRunningLocked(this);
2137 }
2138 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002139
The Android Open Source Project10592532009-03-18 17:39:46 -07002140 public void noteBluetoothOffLocked() {
2141 if (mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002142 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002143 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
2144 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002145 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002146 mBluetoothOn = false;
2147 mBluetoothOnTimer.stopRunningLocked(this);
2148 }
2149 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002150
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002151 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002152
The Android Open Source Project10592532009-03-18 17:39:46 -07002153 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002154 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002155 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002156 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
2157 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002158 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002159 }
2160 mWifiFullLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002161 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002162 }
2163
2164 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002165 mWifiFullLockNesting--;
2166 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002167 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002168 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
2169 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002170 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002171 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002172 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002173 }
2174
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002175 int mWifiScanLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002176
The Android Open Source Project10592532009-03-18 17:39:46 -07002177 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002178 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002179 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002180 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: "
2181 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002182 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002183 }
2184 mWifiScanLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002185 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002186 }
2187
2188 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002189 mWifiScanLockNesting--;
2190 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002191 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002192 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: "
2193 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002194 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002195 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002196 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002197 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002198
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002199 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002200
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002201 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002202 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002203 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002204 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
2205 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002206 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002207 }
2208 mWifiMulticastNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002209 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002210 }
2211
2212 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002213 mWifiMulticastNesting--;
2214 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002215 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002216 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
2217 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002218 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002219 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002220 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002221 }
2222
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002223 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2224 int N = ws.size();
2225 for (int i=0; i<N; i++) {
2226 noteFullWifiLockAcquiredLocked(ws.get(i));
2227 }
2228 }
2229
2230 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
2231 int N = ws.size();
2232 for (int i=0; i<N; i++) {
2233 noteFullWifiLockReleasedLocked(ws.get(i));
2234 }
2235 }
2236
2237 public void noteScanWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2238 int N = ws.size();
2239 for (int i=0; i<N; i++) {
2240 noteScanWifiLockAcquiredLocked(ws.get(i));
2241 }
2242 }
2243
2244 public void noteScanWifiLockReleasedFromSourceLocked(WorkSource ws) {
2245 int N = ws.size();
2246 for (int i=0; i<N; i++) {
2247 noteScanWifiLockReleasedLocked(ws.get(i));
2248 }
2249 }
2250
2251 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
2252 int N = ws.size();
2253 for (int i=0; i<N; i++) {
2254 noteWifiMulticastEnabledLocked(ws.get(i));
2255 }
2256 }
2257
2258 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
2259 int N = ws.size();
2260 for (int i=0; i<N; i++) {
2261 noteWifiMulticastDisabledLocked(ws.get(i));
2262 }
2263 }
2264
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002265 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
2266 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
2267 mMobileIfaces.add(iface);
2268 } else {
2269 mMobileIfaces.remove(iface);
2270 }
2271 }
2272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002273 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002274 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002276
Dianne Hackborn617f8772009-03-31 15:04:46 -07002277 @Override public long getScreenBrightnessTime(int brightnessBin,
2278 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002279 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07002280 batteryRealtime, which);
2281 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002282
Dianne Hackborn617f8772009-03-31 15:04:46 -07002283 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002284 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002285 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002287 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002288 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002290
Dianne Hackborn627bba72009-03-24 22:32:56 -07002291 @Override public long getPhoneSignalStrengthTime(int strengthBin,
2292 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002293 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002294 batteryRealtime, which);
2295 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002296
2297 @Override public long getPhoneSignalScanningTime(
2298 long batteryRealtime, int which) {
2299 return mPhoneSignalScanningTimer.getTotalTimeLocked(
2300 batteryRealtime, which);
2301 }
2302
Dianne Hackborn617f8772009-03-31 15:04:46 -07002303 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002304 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002305 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002306
Dianne Hackborn627bba72009-03-24 22:32:56 -07002307 @Override public long getPhoneDataConnectionTime(int dataType,
2308 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002309 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002310 batteryRealtime, which);
2311 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002312
Dianne Hackborn617f8772009-03-31 15:04:46 -07002313 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002314 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002315 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002316
The Android Open Source Project10592532009-03-18 17:39:46 -07002317 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002318 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002319 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002320
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002321 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) {
2322 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002323 }
2324
The Android Open Source Project10592532009-03-18 17:39:46 -07002325 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002326 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002327 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002329 @Override public boolean getIsOnBattery() {
2330 return mOnBattery;
2331 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
2334 return mUidStats;
2335 }
2336
2337 /**
2338 * The statistics associated with a particular uid.
2339 */
2340 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 final int mUid;
2343 long mLoadedTcpBytesReceived;
2344 long mLoadedTcpBytesSent;
2345 long mCurrentTcpBytesReceived;
2346 long mCurrentTcpBytesSent;
2347 long mTcpBytesReceivedAtLastUnplug;
2348 long mTcpBytesSentAtLastUnplug;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002350 // These are not saved/restored when parcelling, since we want
2351 // to return from the parcel with a snapshot of the state.
2352 long mStartedTcpBytesReceived = -1;
2353 long mStartedTcpBytesSent = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002354
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002355 boolean mWifiRunning;
2356 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002357
The Android Open Source Project10592532009-03-18 17:39:46 -07002358 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002359 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002360
The Android Open Source Project10592532009-03-18 17:39:46 -07002361 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002362 StopwatchTimer mScanWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002363
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002364 boolean mWifiMulticastEnabled;
2365 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002366
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002367 boolean mAudioTurnedOn;
2368 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002369
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002370 boolean mVideoTurnedOn;
2371 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002372
Dianne Hackborn617f8772009-03-31 15:04:46 -07002373 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 /**
2376 * The statistics we have collected for this uid's wake locks.
2377 */
2378 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
2379
2380 /**
2381 * The statistics we have collected for this uid's sensor activations.
2382 */
2383 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
2384
2385 /**
2386 * The statistics we have collected for this uid's processes.
2387 */
2388 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
2389
2390 /**
2391 * The statistics we have collected for this uid's processes.
2392 */
2393 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002394
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002395 /**
2396 * The transient wake stats we have collected for this uid's pids.
2397 */
2398 final SparseArray<Pid> mPids = new SparseArray<Pid>();
2399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 public Uid(int uid) {
2401 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002402 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2403 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002404 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002405 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002406 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002407 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002408 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002409 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002410 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
2411 null, mUnpluggables);
2412 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
2413 null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 }
2415
2416 @Override
2417 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
2418 return mWakelockStats;
2419 }
2420
2421 @Override
2422 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
2423 return mSensorStats;
2424 }
2425
2426 @Override
2427 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
2428 return mProcessStats;
2429 }
2430
2431 @Override
2432 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
2433 return mPackageStats;
2434 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002435
2436 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002437 public int getUid() {
2438 return mUid;
2439 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002440
2441 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 public long getTcpBytesReceived(int which) {
2443 if (which == STATS_LAST) {
2444 return mLoadedTcpBytesReceived;
2445 } else {
2446 long current = computeCurrentTcpBytesReceived();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002447 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 current -= mTcpBytesReceivedAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002449 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 current += mLoadedTcpBytesReceived;
2451 }
2452 return current;
2453 }
2454 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 public long computeCurrentTcpBytesReceived() {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002457 final long uidRxBytes = getNetworkStatsDetailGroupedByUid().getTotal(
2458 null, mUid).rxBytes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002460 ? (uidRxBytes - mStartedTcpBytesReceived) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002462
2463 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002464 public long getTcpBytesSent(int which) {
2465 if (which == STATS_LAST) {
2466 return mLoadedTcpBytesSent;
2467 } else {
2468 long current = computeCurrentTcpBytesSent();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002469 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002470 current -= mTcpBytesSentAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002471 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 current += mLoadedTcpBytesSent;
2473 }
2474 return current;
2475 }
2476 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002477
The Android Open Source Project10592532009-03-18 17:39:46 -07002478 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002479 public void noteWifiRunningLocked() {
2480 if (!mWifiRunning) {
2481 mWifiRunning = true;
2482 if (mWifiRunningTimer == null) {
2483 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2484 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002485 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002486 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002487 }
2488 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002489
Dianne Hackborn617f8772009-03-31 15:04:46 -07002490 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002491 public void noteWifiStoppedLocked() {
2492 if (mWifiRunning) {
2493 mWifiRunning = false;
2494 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002495 }
2496 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002497
Dianne Hackborn617f8772009-03-31 15:04:46 -07002498 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002499 public void noteFullWifiLockAcquiredLocked() {
2500 if (!mFullWifiLockOut) {
2501 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002502 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002503 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002504 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002505 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002506 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2507 }
2508 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002509
The Android Open Source Project10592532009-03-18 17:39:46 -07002510 @Override
2511 public void noteFullWifiLockReleasedLocked() {
2512 if (mFullWifiLockOut) {
2513 mFullWifiLockOut = false;
2514 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2515 }
2516 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002517
The Android Open Source Project10592532009-03-18 17:39:46 -07002518 @Override
2519 public void noteScanWifiLockAcquiredLocked() {
2520 if (!mScanWifiLockOut) {
2521 mScanWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002522 if (mScanWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002523 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002524 mScanWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002525 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002526 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2527 }
2528 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002529
The Android Open Source Project10592532009-03-18 17:39:46 -07002530 @Override
2531 public void noteScanWifiLockReleasedLocked() {
2532 if (mScanWifiLockOut) {
2533 mScanWifiLockOut = false;
2534 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2535 }
2536 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002537
2538 @Override
2539 public void noteWifiMulticastEnabledLocked() {
2540 if (!mWifiMulticastEnabled) {
2541 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002542 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002543 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002544 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002545 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002546 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
2547 }
2548 }
2549
2550 @Override
2551 public void noteWifiMulticastDisabledLocked() {
2552 if (mWifiMulticastEnabled) {
2553 mWifiMulticastEnabled = false;
2554 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
2555 }
2556 }
2557
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002558 @Override
2559 public void noteAudioTurnedOnLocked() {
2560 if (!mAudioTurnedOn) {
2561 mAudioTurnedOn = true;
2562 if (mAudioTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002563 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002564 null, mUnpluggables);
2565 }
2566 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2567 }
2568 }
2569
2570 @Override
2571 public void noteAudioTurnedOffLocked() {
2572 if (mAudioTurnedOn) {
2573 mAudioTurnedOn = false;
2574 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2575 }
2576 }
2577
2578 @Override
2579 public void noteVideoTurnedOnLocked() {
2580 if (!mVideoTurnedOn) {
2581 mVideoTurnedOn = true;
2582 if (mVideoTurnedOnTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002583 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002584 null, mUnpluggables);
2585 }
2586 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2587 }
2588 }
2589
2590 @Override
2591 public void noteVideoTurnedOffLocked() {
2592 if (mVideoTurnedOn) {
2593 mVideoTurnedOn = false;
2594 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2595 }
2596 }
2597
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002598 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002599 public long getWifiRunningTime(long batteryRealtime, int which) {
2600 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002601 return 0;
2602 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002603 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002604 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002605
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002606 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002607 public long getFullWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002608 if (mFullWifiLockTimer == null) {
2609 return 0;
2610 }
Evan Millarc64edde2009-04-18 12:26:32 -07002611 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002612 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002613
2614 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002615 public long getScanWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002616 if (mScanWifiLockTimer == null) {
2617 return 0;
2618 }
Evan Millarc64edde2009-04-18 12:26:32 -07002619 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002620 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002621
2622 @Override
2623 public long getWifiMulticastTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002624 if (mWifiMulticastTimer == null) {
2625 return 0;
2626 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002627 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
2628 which);
2629 }
2630
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002631 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002632 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
2633 if (mAudioTurnedOnTimer == null) {
2634 return 0;
2635 }
2636 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2637 }
2638
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002639 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002640 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
2641 if (mVideoTurnedOnTimer == null) {
2642 return 0;
2643 }
2644 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2645 }
2646
Dianne Hackborn617f8772009-03-31 15:04:46 -07002647 @Override
2648 public void noteUserActivityLocked(int type) {
2649 if (mUserActivityCounters == null) {
2650 initUserActivityLocked();
2651 }
2652 if (type < 0) type = 0;
2653 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
Christopher Tate4cee7252010-03-19 14:50:40 -07002654 mUserActivityCounters[type].stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002655 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002656
Dianne Hackborn617f8772009-03-31 15:04:46 -07002657 @Override
2658 public boolean hasUserActivity() {
2659 return mUserActivityCounters != null;
2660 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002661
Dianne Hackborn617f8772009-03-31 15:04:46 -07002662 @Override
2663 public int getUserActivityCount(int type, int which) {
2664 if (mUserActivityCounters == null) {
2665 return 0;
2666 }
Evan Millarc64edde2009-04-18 12:26:32 -07002667 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002668 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002669
Dianne Hackborn617f8772009-03-31 15:04:46 -07002670 void initUserActivityLocked() {
2671 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2672 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2673 mUserActivityCounters[i] = new Counter(mUnpluggables);
2674 }
2675 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002677 public long computeCurrentTcpBytesSent() {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002678 final long uidTxBytes = getNetworkStatsDetailGroupedByUid().getTotal(
2679 null, mUid).txBytes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002681 ? (uidTxBytes - mStartedTcpBytesSent) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002683
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002684 /**
2685 * Clear all stats for this uid. Returns true if the uid is completely
2686 * inactive so can be dropped.
2687 */
2688 boolean reset() {
2689 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002690
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002691 if (mWifiRunningTimer != null) {
2692 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false);
2693 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002694 }
2695 if (mFullWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002696 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002697 active |= mFullWifiLockOut;
2698 }
2699 if (mScanWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002700 active |= !mScanWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002701 active |= mScanWifiLockOut;
2702 }
2703 if (mWifiMulticastTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002704 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002705 active |= mWifiMulticastEnabled;
2706 }
2707 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002708 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002709 active |= mAudioTurnedOn;
2710 }
2711 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002712 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002713 active |= mVideoTurnedOn;
2714 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002715
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002716 mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0;
2717 mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002718
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002719 if (mUserActivityCounters != null) {
2720 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2721 mUserActivityCounters[i].reset(false);
2722 }
2723 }
2724
2725 if (mWakelockStats.size() > 0) {
2726 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
2727 while (it.hasNext()) {
2728 Map.Entry<String, Wakelock> wakelockEntry = it.next();
2729 Wakelock wl = wakelockEntry.getValue();
2730 if (wl.reset()) {
2731 it.remove();
2732 } else {
2733 active = true;
2734 }
2735 }
2736 }
2737 if (mSensorStats.size() > 0) {
2738 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
2739 while (it.hasNext()) {
2740 Map.Entry<Integer, Sensor> sensorEntry = it.next();
2741 Sensor s = sensorEntry.getValue();
2742 if (s.reset()) {
2743 it.remove();
2744 } else {
2745 active = true;
2746 }
2747 }
2748 }
2749 if (mProcessStats.size() > 0) {
2750 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
2751 while (it.hasNext()) {
2752 Map.Entry<String, Proc> procEntry = it.next();
2753 procEntry.getValue().detach();
2754 }
2755 mProcessStats.clear();
2756 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002757 if (mPids.size() > 0) {
2758 for (int i=0; !active && i<mPids.size(); i++) {
2759 Pid pid = mPids.valueAt(i);
2760 if (pid.mWakeStart != 0) {
2761 active = true;
2762 }
2763 }
2764 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002765 if (mPackageStats.size() > 0) {
2766 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
2767 while (it.hasNext()) {
2768 Map.Entry<String, Pkg> pkgEntry = it.next();
2769 Pkg p = pkgEntry.getValue();
2770 p.detach();
2771 if (p.mServiceStats.size() > 0) {
2772 Iterator<Map.Entry<String, Pkg.Serv>> it2
2773 = p.mServiceStats.entrySet().iterator();
2774 while (it2.hasNext()) {
2775 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
2776 servEntry.getValue().detach();
2777 }
2778 }
2779 }
2780 mPackageStats.clear();
2781 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002782
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002783 mPids.clear();
2784
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002785 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002786 if (mWifiRunningTimer != null) {
2787 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002788 }
2789 if (mFullWifiLockTimer != null) {
2790 mFullWifiLockTimer.detach();
2791 }
2792 if (mScanWifiLockTimer != null) {
2793 mScanWifiLockTimer.detach();
2794 }
2795 if (mWifiMulticastTimer != null) {
2796 mWifiMulticastTimer.detach();
2797 }
2798 if (mAudioTurnedOnTimer != null) {
2799 mAudioTurnedOnTimer.detach();
2800 }
2801 if (mVideoTurnedOnTimer != null) {
2802 mVideoTurnedOnTimer.detach();
2803 }
2804 if (mUserActivityCounters != null) {
2805 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2806 mUserActivityCounters[i].detach();
2807 }
2808 }
2809 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002810
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002811 return !active;
2812 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2815 out.writeInt(mWakelockStats.size());
2816 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
2817 out.writeString(wakelockEntry.getKey());
2818 Uid.Wakelock wakelock = wakelockEntry.getValue();
2819 wakelock.writeToParcelLocked(out, batteryRealtime);
2820 }
2821
2822 out.writeInt(mSensorStats.size());
2823 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
2824 out.writeInt(sensorEntry.getKey());
2825 Uid.Sensor sensor = sensorEntry.getValue();
2826 sensor.writeToParcelLocked(out, batteryRealtime);
2827 }
2828
2829 out.writeInt(mProcessStats.size());
2830 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
2831 out.writeString(procEntry.getKey());
2832 Uid.Proc proc = procEntry.getValue();
2833 proc.writeToParcelLocked(out);
2834 }
2835
2836 out.writeInt(mPackageStats.size());
2837 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
2838 out.writeString(pkgEntry.getKey());
2839 Uid.Pkg pkg = pkgEntry.getValue();
2840 pkg.writeToParcelLocked(out);
2841 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 out.writeLong(mLoadedTcpBytesReceived);
2844 out.writeLong(mLoadedTcpBytesSent);
2845 out.writeLong(computeCurrentTcpBytesReceived());
2846 out.writeLong(computeCurrentTcpBytesSent());
2847 out.writeLong(mTcpBytesReceivedAtLastUnplug);
2848 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002849 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002850 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002851 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002852 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002853 out.writeInt(0);
2854 }
2855 if (mFullWifiLockTimer != null) {
2856 out.writeInt(1);
2857 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
2858 } else {
2859 out.writeInt(0);
2860 }
2861 if (mScanWifiLockTimer != null) {
2862 out.writeInt(1);
2863 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
2864 } else {
2865 out.writeInt(0);
2866 }
2867 if (mWifiMulticastTimer != null) {
2868 out.writeInt(1);
2869 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
2870 } else {
2871 out.writeInt(0);
2872 }
2873 if (mAudioTurnedOnTimer != null) {
2874 out.writeInt(1);
2875 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
2876 } else {
2877 out.writeInt(0);
2878 }
2879 if (mVideoTurnedOnTimer != null) {
2880 out.writeInt(1);
2881 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
2882 } else {
2883 out.writeInt(0);
2884 }
2885 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002886 out.writeInt(1);
2887 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2888 mUserActivityCounters[i].writeToParcel(out);
2889 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002890 } else {
2891 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 }
2894
2895 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2896 int numWakelocks = in.readInt();
2897 mWakelockStats.clear();
2898 for (int j = 0; j < numWakelocks; j++) {
2899 String wakelockName = in.readString();
2900 Uid.Wakelock wakelock = new Wakelock();
2901 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackbornc24ab862011-10-18 15:55:03 -07002902 // We will just drop some random set of wakelocks if
2903 // the previous run of the system was an older version
2904 // that didn't impose a limit.
2905 mWakelockStats.put(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 }
2907
2908 int numSensors = in.readInt();
2909 mSensorStats.clear();
2910 for (int k = 0; k < numSensors; k++) {
2911 int sensorNumber = in.readInt();
2912 Uid.Sensor sensor = new Sensor(sensorNumber);
2913 sensor.readFromParcelLocked(mUnpluggables, in);
2914 mSensorStats.put(sensorNumber, sensor);
2915 }
2916
2917 int numProcs = in.readInt();
2918 mProcessStats.clear();
2919 for (int k = 0; k < numProcs; k++) {
2920 String processName = in.readString();
2921 Uid.Proc proc = new Proc();
2922 proc.readFromParcelLocked(in);
2923 mProcessStats.put(processName, proc);
2924 }
2925
2926 int numPkgs = in.readInt();
2927 mPackageStats.clear();
2928 for (int l = 0; l < numPkgs; l++) {
2929 String packageName = in.readString();
2930 Uid.Pkg pkg = new Pkg();
2931 pkg.readFromParcelLocked(in);
2932 mPackageStats.put(packageName, pkg);
2933 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 mLoadedTcpBytesReceived = in.readLong();
2936 mLoadedTcpBytesSent = in.readLong();
2937 mCurrentTcpBytesReceived = in.readLong();
2938 mCurrentTcpBytesSent = in.readLong();
2939 mTcpBytesReceivedAtLastUnplug = in.readLong();
2940 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002941 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002942 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002943 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2944 mWifiRunningTimers, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002945 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002946 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002947 }
2948 mFullWifiLockOut = false;
2949 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002950 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002951 mFullWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002952 } else {
2953 mFullWifiLockTimer = null;
2954 }
2955 mScanWifiLockOut = false;
2956 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002957 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002958 mScanWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002959 } else {
2960 mScanWifiLockTimer = null;
2961 }
2962 mWifiMulticastEnabled = false;
2963 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002964 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002965 mWifiMulticastTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002966 } else {
2967 mWifiMulticastTimer = null;
2968 }
2969 mAudioTurnedOn = false;
2970 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002971 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002972 null, mUnpluggables, in);
2973 } else {
2974 mAudioTurnedOnTimer = null;
2975 }
2976 mVideoTurnedOn = false;
2977 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002978 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002979 null, mUnpluggables, in);
2980 } else {
2981 mVideoTurnedOnTimer = null;
2982 }
2983 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002984 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2985 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2986 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
2987 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002988 } else {
2989 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07002990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002991 }
2992
2993 /**
2994 * The statistics associated with a particular wake lock.
2995 */
2996 public final class Wakelock extends BatteryStats.Uid.Wakelock {
2997 /**
2998 * How long (in ms) this uid has been keeping the device partially awake.
2999 */
Evan Millarc64edde2009-04-18 12:26:32 -07003000 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001
3002 /**
3003 * How long (in ms) this uid has been keeping the device fully awake.
3004 */
Evan Millarc64edde2009-04-18 12:26:32 -07003005 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006
3007 /**
3008 * How long (in ms) this uid has had a window keeping the device awake.
3009 */
Evan Millarc64edde2009-04-18 12:26:32 -07003010 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003011
3012 /**
3013 * Reads a possibly null Timer from a Parcel. The timer is associated with the
3014 * proper timer pool from the given BatteryStatsImpl object.
3015 *
3016 * @param in the Parcel to be read from.
3017 * return a new Timer, or null.
3018 */
Evan Millarc64edde2009-04-18 12:26:32 -07003019 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003020 ArrayList<Unpluggable> unpluggables, Parcel in) {
3021 if (in.readInt() == 0) {
3022 return null;
3023 }
3024
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003025 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 }
3027
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003028 boolean reset() {
3029 boolean wlactive = false;
3030 if (mTimerFull != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003031 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003032 }
3033 if (mTimerPartial != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003034 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003035 }
3036 if (mTimerWindow != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003037 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003038 }
3039 if (!wlactive) {
3040 if (mTimerFull != null) {
3041 mTimerFull.detach();
3042 mTimerFull = null;
3043 }
3044 if (mTimerPartial != null) {
3045 mTimerPartial.detach();
3046 mTimerPartial = null;
3047 }
3048 if (mTimerWindow != null) {
3049 mTimerWindow.detach();
3050 mTimerWindow = null;
3051 }
3052 }
3053 return !wlactive;
3054 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003056 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3057 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
3058 mPartialTimers, unpluggables, in);
3059 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
3060 mFullTimers, unpluggables, in);
3061 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
3062 mWindowTimers, unpluggables, in);
3063 }
3064
3065 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3066 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
3067 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
3068 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
3069 }
3070
3071 @Override
3072 public Timer getWakeTime(int type) {
3073 switch (type) {
3074 case WAKE_TYPE_FULL: return mTimerFull;
3075 case WAKE_TYPE_PARTIAL: return mTimerPartial;
3076 case WAKE_TYPE_WINDOW: return mTimerWindow;
3077 default: throw new IllegalArgumentException("type = " + type);
3078 }
3079 }
3080 }
3081
3082 public final class Sensor extends BatteryStats.Uid.Sensor {
3083 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07003084 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003086 public Sensor(int handle) {
3087 mHandle = handle;
3088 }
3089
Evan Millarc64edde2009-04-18 12:26:32 -07003090 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003091 Parcel in) {
3092 if (in.readInt() == 0) {
3093 return null;
3094 }
3095
Evan Millarc64edde2009-04-18 12:26:32 -07003096 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003097 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003098 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003099 mSensorTimers.put(mHandle, pool);
3100 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003101 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003102 }
3103
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003104 boolean reset() {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003105 if (mTimer.reset(BatteryStatsImpl.this, true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003106 mTimer = null;
3107 return true;
3108 }
3109 return false;
3110 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003112 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3113 mTimer = readTimerFromParcel(unpluggables, in);
3114 }
3115
3116 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3117 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
3118 }
3119
3120 @Override
3121 public Timer getSensorTime() {
3122 return mTimer;
3123 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003124
3125 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003126 public int getHandle() {
3127 return mHandle;
3128 }
3129 }
3130
3131 /**
3132 * The statistics associated with a particular process.
3133 */
3134 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
3135 /**
3136 * Total time (in 1/100 sec) spent executing in user code.
3137 */
3138 long mUserTime;
3139
3140 /**
3141 * Total time (in 1/100 sec) spent executing in kernel code.
3142 */
3143 long mSystemTime;
3144
3145 /**
3146 * Number of times the process has been started.
3147 */
3148 int mStarts;
3149
3150 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003151 * Amount of time the process was running in the foreground.
3152 */
3153 long mForegroundTime;
3154
3155 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003156 * The amount of user time loaded from a previous save.
3157 */
3158 long mLoadedUserTime;
3159
3160 /**
3161 * The amount of system time loaded from a previous save.
3162 */
3163 long mLoadedSystemTime;
3164
3165 /**
3166 * The number of times the process has started from a previous save.
3167 */
3168 int mLoadedStarts;
3169
3170 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003171 * The amount of foreground time loaded from a previous save.
3172 */
3173 long mLoadedForegroundTime;
3174
3175 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 * The amount of user time loaded from the previous run.
3177 */
3178 long mLastUserTime;
3179
3180 /**
3181 * The amount of system time loaded from the previous run.
3182 */
3183 long mLastSystemTime;
3184
3185 /**
3186 * The number of times the process has started from the previous run.
3187 */
3188 int mLastStarts;
3189
3190 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003191 * The amount of foreground time loaded from the previous run
3192 */
3193 long mLastForegroundTime;
3194
3195 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003196 * The amount of user time when last unplugged.
3197 */
3198 long mUnpluggedUserTime;
3199
3200 /**
3201 * The amount of system time when last unplugged.
3202 */
3203 long mUnpluggedSystemTime;
3204
3205 /**
3206 * The number of times the process has started before unplugged.
3207 */
3208 int mUnpluggedStarts;
3209
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003210 /**
3211 * The amount of foreground time since unplugged.
3212 */
3213 long mUnpluggedForegroundTime;
3214
Amith Yamasanie43530a2009-08-21 13:11:37 -07003215 SamplingCounter[] mSpeedBins;
3216
Dianne Hackborn287952c2010-09-22 22:34:31 -07003217 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003219 Proc() {
3220 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003221 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003222 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224 public void unplug(long batteryUptime, long batteryRealtime) {
3225 mUnpluggedUserTime = mUserTime;
3226 mUnpluggedSystemTime = mSystemTime;
3227 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003228 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003229 }
3230
3231 public void plug(long batteryUptime, long batteryRealtime) {
3232 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003233
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003234 void detach() {
3235 mUnpluggables.remove(this);
3236 for (int i = 0; i < mSpeedBins.length; i++) {
3237 SamplingCounter c = mSpeedBins[i];
3238 if (c != null) {
3239 mUnpluggables.remove(c);
3240 mSpeedBins[i] = null;
3241 }
3242 }
3243 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003244
Dianne Hackborn287952c2010-09-22 22:34:31 -07003245 public int countExcessivePowers() {
3246 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003247 }
3248
Dianne Hackborn287952c2010-09-22 22:34:31 -07003249 public ExcessivePower getExcessivePower(int i) {
3250 if (mExcessivePower != null) {
3251 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003252 }
3253 return null;
3254 }
3255
3256 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003257 if (mExcessivePower == null) {
3258 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003259 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07003260 ExcessivePower ew = new ExcessivePower();
3261 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003262 ew.overTime = overTime;
3263 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07003264 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003265 }
3266
Dianne Hackborn287952c2010-09-22 22:34:31 -07003267 public void addExcessiveCpu(long overTime, long usedTime) {
3268 if (mExcessivePower == null) {
3269 mExcessivePower = new ArrayList<ExcessivePower>();
3270 }
3271 ExcessivePower ew = new ExcessivePower();
3272 ew.type = ExcessivePower.TYPE_CPU;
3273 ew.overTime = overTime;
3274 ew.usedTime = usedTime;
3275 mExcessivePower.add(ew);
3276 }
3277
3278 void writeExcessivePowerToParcelLocked(Parcel out) {
3279 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003280 out.writeInt(0);
3281 return;
3282 }
3283
Dianne Hackborn287952c2010-09-22 22:34:31 -07003284 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003285 out.writeInt(N);
3286 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003287 ExcessivePower ew = mExcessivePower.get(i);
3288 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003289 out.writeLong(ew.overTime);
3290 out.writeLong(ew.usedTime);
3291 }
3292 }
3293
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003294 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003295 final int N = in.readInt();
3296 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003297 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003298 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003299 }
3300
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003301 if (N > 10000) {
3302 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
3303 return false;
3304 }
3305
Dianne Hackborn287952c2010-09-22 22:34:31 -07003306 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003307 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003308 ExcessivePower ew = new ExcessivePower();
3309 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003310 ew.overTime = in.readLong();
3311 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07003312 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003313 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003314 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003315 }
3316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003317 void writeToParcelLocked(Parcel out) {
3318 out.writeLong(mUserTime);
3319 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003320 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321 out.writeInt(mStarts);
3322 out.writeLong(mLoadedUserTime);
3323 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003324 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326 out.writeLong(mUnpluggedUserTime);
3327 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003328 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003330
3331 out.writeInt(mSpeedBins.length);
3332 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003333 SamplingCounter c = mSpeedBins[i];
3334 if (c != null) {
3335 out.writeInt(1);
3336 c.writeToParcel(out);
3337 } else {
3338 out.writeInt(0);
3339 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003340 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003341
Dianne Hackborn287952c2010-09-22 22:34:31 -07003342 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343 }
3344
3345 void readFromParcelLocked(Parcel in) {
3346 mUserTime = in.readLong();
3347 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003348 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 mStarts = in.readInt();
3350 mLoadedUserTime = in.readLong();
3351 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003352 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003354 mLastUserTime = 0;
3355 mLastSystemTime = 0;
3356 mLastForegroundTime = 0;
3357 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 mUnpluggedUserTime = in.readLong();
3359 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003360 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003361 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07003362
3363 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003364 int steps = getCpuSpeedSteps();
3365 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07003366 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003367 if (in.readInt() != 0) {
3368 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
3369 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003370 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003371
Dianne Hackborn287952c2010-09-22 22:34:31 -07003372 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373 }
3374
3375 public BatteryStatsImpl getBatteryStats() {
3376 return BatteryStatsImpl.this;
3377 }
3378
3379 public void addCpuTimeLocked(int utime, int stime) {
3380 mUserTime += utime;
3381 mSystemTime += stime;
3382 }
3383
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003384 public void addForegroundTimeLocked(long ttime) {
3385 mForegroundTime += ttime;
3386 }
3387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388 public void incStartsLocked() {
3389 mStarts++;
3390 }
3391
3392 @Override
3393 public long getUserTime(int which) {
3394 long val;
3395 if (which == STATS_LAST) {
3396 val = mLastUserTime;
3397 } else {
3398 val = mUserTime;
3399 if (which == STATS_CURRENT) {
3400 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003401 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003402 val -= mUnpluggedUserTime;
3403 }
3404 }
3405 return val;
3406 }
3407
3408 @Override
3409 public long getSystemTime(int which) {
3410 long val;
3411 if (which == STATS_LAST) {
3412 val = mLastSystemTime;
3413 } else {
3414 val = mSystemTime;
3415 if (which == STATS_CURRENT) {
3416 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003417 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 val -= mUnpluggedSystemTime;
3419 }
3420 }
3421 return val;
3422 }
3423
3424 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003425 public long getForegroundTime(int which) {
3426 long val;
3427 if (which == STATS_LAST) {
3428 val = mLastForegroundTime;
3429 } else {
3430 val = mForegroundTime;
3431 if (which == STATS_CURRENT) {
3432 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003433 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003434 val -= mUnpluggedForegroundTime;
3435 }
3436 }
3437 return val;
3438 }
3439
3440 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 public int getStarts(int which) {
3442 int val;
3443 if (which == STATS_LAST) {
3444 val = mLastStarts;
3445 } else {
3446 val = mStarts;
3447 if (which == STATS_CURRENT) {
3448 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003449 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003450 val -= mUnpluggedStarts;
3451 }
3452 }
3453 return val;
3454 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003455
3456 /* Called by ActivityManagerService when CPU times are updated. */
3457 public void addSpeedStepTimes(long[] values) {
3458 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003459 long amt = values[i];
3460 if (amt != 0) {
3461 SamplingCounter c = mSpeedBins[i];
3462 if (c == null) {
3463 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
3464 }
3465 c.addCountAtomic(values[i]);
3466 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003467 }
3468 }
3469
3470 @Override
3471 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
3472 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003473 SamplingCounter c = mSpeedBins[speedStep];
3474 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07003475 } else {
3476 return 0;
3477 }
3478 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003479 }
3480
3481 /**
3482 * The statistics associated with a particular package.
3483 */
3484 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
3485 /**
3486 * Number of times this package has done something that could wake up the
3487 * device from sleep.
3488 */
3489 int mWakeups;
3490
3491 /**
3492 * Number of things that could wake up the device loaded from a
3493 * previous save.
3494 */
3495 int mLoadedWakeups;
3496
3497 /**
3498 * Number of things that could wake up the device as of the
3499 * last run.
3500 */
3501 int mLastWakeups;
3502
3503 /**
3504 * Number of things that could wake up the device as of the
3505 * last run.
3506 */
3507 int mUnpluggedWakeups;
3508
3509 /**
3510 * The statics we have collected for this package's services.
3511 */
3512 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
3513
3514 Pkg() {
3515 mUnpluggables.add(this);
3516 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518 public void unplug(long batteryUptime, long batteryRealtime) {
3519 mUnpluggedWakeups = mWakeups;
3520 }
3521
3522 public void plug(long batteryUptime, long batteryRealtime) {
3523 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003524
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003525 void detach() {
3526 mUnpluggables.remove(this);
3527 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003529 void readFromParcelLocked(Parcel in) {
3530 mWakeups = in.readInt();
3531 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003532 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003533 mUnpluggedWakeups = in.readInt();
3534
3535 int numServs = in.readInt();
3536 mServiceStats.clear();
3537 for (int m = 0; m < numServs; m++) {
3538 String serviceName = in.readString();
3539 Uid.Pkg.Serv serv = new Serv();
3540 mServiceStats.put(serviceName, serv);
3541
3542 serv.readFromParcelLocked(in);
3543 }
3544 }
3545
3546 void writeToParcelLocked(Parcel out) {
3547 out.writeInt(mWakeups);
3548 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 out.writeInt(mUnpluggedWakeups);
3550
3551 out.writeInt(mServiceStats.size());
3552 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
3553 out.writeString(servEntry.getKey());
3554 Uid.Pkg.Serv serv = servEntry.getValue();
3555
3556 serv.writeToParcelLocked(out);
3557 }
3558 }
3559
3560 @Override
3561 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
3562 return mServiceStats;
3563 }
3564
3565 @Override
3566 public int getWakeups(int which) {
3567 int val;
3568 if (which == STATS_LAST) {
3569 val = mLastWakeups;
3570 } else {
3571 val = mWakeups;
3572 if (which == STATS_CURRENT) {
3573 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003574 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003575 val -= mUnpluggedWakeups;
3576 }
3577 }
3578
3579 return val;
3580 }
3581
3582 /**
3583 * The statistics associated with a particular service.
3584 */
3585 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
3586 /**
3587 * Total time (ms in battery uptime) the service has been left started.
3588 */
3589 long mStartTime;
3590
3591 /**
3592 * If service has been started and not yet stopped, this is
3593 * when it was started.
3594 */
3595 long mRunningSince;
3596
3597 /**
3598 * True if we are currently running.
3599 */
3600 boolean mRunning;
3601
3602 /**
3603 * Total number of times startService() has been called.
3604 */
3605 int mStarts;
3606
3607 /**
3608 * Total time (ms in battery uptime) the service has been left launched.
3609 */
3610 long mLaunchedTime;
3611
3612 /**
3613 * If service has been launched and not yet exited, this is
3614 * when it was launched (ms in battery uptime).
3615 */
3616 long mLaunchedSince;
3617
3618 /**
3619 * True if we are currently launched.
3620 */
3621 boolean mLaunched;
3622
3623 /**
3624 * Total number times the service has been launched.
3625 */
3626 int mLaunches;
3627
3628 /**
3629 * The amount of time spent started loaded from a previous save
3630 * (ms in battery uptime).
3631 */
3632 long mLoadedStartTime;
3633
3634 /**
3635 * The number of starts loaded from a previous save.
3636 */
3637 int mLoadedStarts;
3638
3639 /**
3640 * The number of launches loaded from a previous save.
3641 */
3642 int mLoadedLaunches;
3643
3644 /**
3645 * The amount of time spent started as of the last run (ms
3646 * in battery uptime).
3647 */
3648 long mLastStartTime;
3649
3650 /**
3651 * The number of starts as of the last run.
3652 */
3653 int mLastStarts;
3654
3655 /**
3656 * The number of launches as of the last run.
3657 */
3658 int mLastLaunches;
3659
3660 /**
3661 * The amount of time spent started when last unplugged (ms
3662 * in battery uptime).
3663 */
3664 long mUnpluggedStartTime;
3665
3666 /**
3667 * The number of starts when last unplugged.
3668 */
3669 int mUnpluggedStarts;
3670
3671 /**
3672 * The number of launches when last unplugged.
3673 */
3674 int mUnpluggedLaunches;
3675
3676 Serv() {
3677 mUnpluggables.add(this);
3678 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 public void unplug(long batteryUptime, long batteryRealtime) {
3681 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
3682 mUnpluggedStarts = mStarts;
3683 mUnpluggedLaunches = mLaunches;
3684 }
3685
3686 public void plug(long batteryUptime, long batteryRealtime) {
3687 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003688
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003689 void detach() {
3690 mUnpluggables.remove(this);
3691 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003693 void readFromParcelLocked(Parcel in) {
3694 mStartTime = in.readLong();
3695 mRunningSince = in.readLong();
3696 mRunning = in.readInt() != 0;
3697 mStarts = in.readInt();
3698 mLaunchedTime = in.readLong();
3699 mLaunchedSince = in.readLong();
3700 mLaunched = in.readInt() != 0;
3701 mLaunches = in.readInt();
3702 mLoadedStartTime = in.readLong();
3703 mLoadedStarts = in.readInt();
3704 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003705 mLastStartTime = 0;
3706 mLastStarts = 0;
3707 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 mUnpluggedStartTime = in.readLong();
3709 mUnpluggedStarts = in.readInt();
3710 mUnpluggedLaunches = in.readInt();
3711 }
3712
3713 void writeToParcelLocked(Parcel out) {
3714 out.writeLong(mStartTime);
3715 out.writeLong(mRunningSince);
3716 out.writeInt(mRunning ? 1 : 0);
3717 out.writeInt(mStarts);
3718 out.writeLong(mLaunchedTime);
3719 out.writeLong(mLaunchedSince);
3720 out.writeInt(mLaunched ? 1 : 0);
3721 out.writeInt(mLaunches);
3722 out.writeLong(mLoadedStartTime);
3723 out.writeInt(mLoadedStarts);
3724 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 out.writeLong(mUnpluggedStartTime);
3726 out.writeInt(mUnpluggedStarts);
3727 out.writeInt(mUnpluggedLaunches);
3728 }
3729
3730 long getLaunchTimeToNowLocked(long batteryUptime) {
3731 if (!mLaunched) return mLaunchedTime;
3732 return mLaunchedTime + batteryUptime - mLaunchedSince;
3733 }
3734
3735 long getStartTimeToNowLocked(long batteryUptime) {
3736 if (!mRunning) return mStartTime;
3737 return mStartTime + batteryUptime - mRunningSince;
3738 }
3739
3740 public void startLaunchedLocked() {
3741 if (!mLaunched) {
3742 mLaunches++;
3743 mLaunchedSince = getBatteryUptimeLocked();
3744 mLaunched = true;
3745 }
3746 }
3747
3748 public void stopLaunchedLocked() {
3749 if (mLaunched) {
3750 long time = getBatteryUptimeLocked() - mLaunchedSince;
3751 if (time > 0) {
3752 mLaunchedTime += time;
3753 } else {
3754 mLaunches--;
3755 }
3756 mLaunched = false;
3757 }
3758 }
3759
3760 public void startRunningLocked() {
3761 if (!mRunning) {
3762 mStarts++;
3763 mRunningSince = getBatteryUptimeLocked();
3764 mRunning = true;
3765 }
3766 }
3767
3768 public void stopRunningLocked() {
3769 if (mRunning) {
3770 long time = getBatteryUptimeLocked() - mRunningSince;
3771 if (time > 0) {
3772 mStartTime += time;
3773 } else {
3774 mStarts--;
3775 }
3776 mRunning = false;
3777 }
3778 }
3779
3780 public BatteryStatsImpl getBatteryStats() {
3781 return BatteryStatsImpl.this;
3782 }
3783
3784 @Override
3785 public int getLaunches(int which) {
3786 int val;
3787
3788 if (which == STATS_LAST) {
3789 val = mLastLaunches;
3790 } else {
3791 val = mLaunches;
3792 if (which == STATS_CURRENT) {
3793 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003794 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 val -= mUnpluggedLaunches;
3796 }
3797 }
3798
3799 return val;
3800 }
3801
3802 @Override
3803 public long getStartTime(long now, int which) {
3804 long val;
3805 if (which == STATS_LAST) {
3806 val = mLastStartTime;
3807 } else {
3808 val = getStartTimeToNowLocked(now);
3809 if (which == STATS_CURRENT) {
3810 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003811 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 val -= mUnpluggedStartTime;
3813 }
3814 }
3815
3816 return val;
3817 }
3818
3819 @Override
3820 public int getStarts(int which) {
3821 int val;
3822 if (which == STATS_LAST) {
3823 val = mLastStarts;
3824 } else {
3825 val = mStarts;
3826 if (which == STATS_CURRENT) {
3827 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003828 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003829 val -= mUnpluggedStarts;
3830 }
3831 }
3832
3833 return val;
3834 }
3835 }
3836
3837 public BatteryStatsImpl getBatteryStats() {
3838 return BatteryStatsImpl.this;
3839 }
3840
3841 public void incWakeupsLocked() {
3842 mWakeups++;
3843 }
3844
3845 final Serv newServiceStatsLocked() {
3846 return new Serv();
3847 }
3848 }
3849
3850 /**
3851 * Retrieve the statistics object for a particular process, creating
3852 * if needed.
3853 */
3854 public Proc getProcessStatsLocked(String name) {
3855 Proc ps = mProcessStats.get(name);
3856 if (ps == null) {
3857 ps = new Proc();
3858 mProcessStats.put(name, ps);
3859 }
3860
3861 return ps;
3862 }
3863
Dianne Hackbornb5e31652010-09-07 12:13:55 -07003864 public SparseArray<? extends Pid> getPidStats() {
3865 return mPids;
3866 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003867
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003868 public Pid getPidStatsLocked(int pid) {
3869 Pid p = mPids.get(pid);
3870 if (p == null) {
3871 p = new Pid();
3872 mPids.put(pid, p);
3873 }
3874 return p;
3875 }
3876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003877 /**
3878 * Retrieve the statistics object for a particular service, creating
3879 * if needed.
3880 */
3881 public Pkg getPackageStatsLocked(String name) {
3882 Pkg ps = mPackageStats.get(name);
3883 if (ps == null) {
3884 ps = new Pkg();
3885 mPackageStats.put(name, ps);
3886 }
3887
3888 return ps;
3889 }
3890
3891 /**
3892 * Retrieve the statistics object for a particular service, creating
3893 * if needed.
3894 */
3895 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
3896 Pkg ps = getPackageStatsLocked(pkg);
3897 Pkg.Serv ss = ps.mServiceStats.get(serv);
3898 if (ss == null) {
3899 ss = ps.newServiceStatsLocked();
3900 ps.mServiceStats.put(serv, ss);
3901 }
3902
3903 return ss;
3904 }
3905
Evan Millarc64edde2009-04-18 12:26:32 -07003906 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003907 Wakelock wl = mWakelockStats.get(name);
3908 if (wl == null) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07003909 final int N = mWakelockStats.size();
3910 if (N > MAX_WAKELOCKS_PER_UID && (mUid != Process.SYSTEM_UID
3911 || N > MAX_WAKELOCKS_PER_UID_IN_SYSTEM)) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08003912 name = BATCHED_WAKELOCK_NAME;
3913 wl = mWakelockStats.get(name);
3914 }
3915 if (wl == null) {
3916 wl = new Wakelock();
3917 mWakelockStats.put(name, wl);
3918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 }
Evan Millarc64edde2009-04-18 12:26:32 -07003920 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003921 switch (type) {
3922 case WAKE_TYPE_PARTIAL:
3923 t = wl.mTimerPartial;
3924 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003925 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
3926 mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003927 wl.mTimerPartial = t;
3928 }
3929 return t;
3930 case WAKE_TYPE_FULL:
3931 t = wl.mTimerFull;
3932 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003933 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
3934 mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 wl.mTimerFull = t;
3936 }
3937 return t;
3938 case WAKE_TYPE_WINDOW:
3939 t = wl.mTimerWindow;
3940 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003941 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
3942 mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 wl.mTimerWindow = t;
3944 }
3945 return t;
3946 default:
3947 throw new IllegalArgumentException("type=" + type);
3948 }
3949 }
3950
Evan Millarc64edde2009-04-18 12:26:32 -07003951 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952 Sensor se = mSensorStats.get(sensor);
3953 if (se == null) {
3954 if (!create) {
3955 return null;
3956 }
3957 se = new Sensor(sensor);
3958 mSensorStats.put(sensor, se);
3959 }
Evan Millarc64edde2009-04-18 12:26:32 -07003960 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 if (t != null) {
3962 return t;
3963 }
Evan Millarc64edde2009-04-18 12:26:32 -07003964 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003966 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 mSensorTimers.put(sensor, timers);
3968 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003969 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 se.mTimer = t;
3971 return t;
3972 }
3973
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003974 public void noteStartWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003975 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003976 if (t != null) {
3977 t.startRunningLocked(BatteryStatsImpl.this);
3978 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003979 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003980 Pid p = getPidStatsLocked(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003981 if (p.mWakeStart == 0) {
3982 p.mWakeStart = SystemClock.elapsedRealtime();
3983 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003985 }
3986
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003987 public void noteStopWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003988 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003989 if (t != null) {
3990 t.stopRunningLocked(BatteryStatsImpl.this);
3991 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003992 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003993 Pid p = mPids.get(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07003994 if (p != null && p.mWakeStart != 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003995 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
3996 p.mWakeStart = 0;
3997 }
3998 }
3999 }
4000
4001 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
4002 Proc p = getProcessStatsLocked(proc);
4003 if (p != null) {
4004 p.addExcessiveWake(overTime, usedTime);
4005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004006 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004007
Dianne Hackborn287952c2010-09-22 22:34:31 -07004008 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
4009 Proc p = getProcessStatsLocked(proc);
4010 if (p != null) {
4011 p.addExcessiveCpu(overTime, usedTime);
4012 }
4013 }
4014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07004016 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004017 if (t != null) {
4018 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004020 }
4021
4022 public void noteStopSensor(int sensor) {
4023 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07004024 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 if (t != null) {
4026 t.stopRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004030 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004031 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004032 if (t != null) {
4033 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004034 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004035 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004037 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004038 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 if (t != null) {
4040 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004041 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004042 }
4043
4044 public BatteryStatsImpl getBatteryStats() {
4045 return BatteryStatsImpl.this;
4046 }
4047 }
4048
4049 public BatteryStatsImpl(String filename) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004050 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004051 mHandler = new MyHandler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 mStartCount++;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004053 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004054 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004055 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004056 }
4057 mInputEventCounter = new Counter(mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004058 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
Wink Saville52840902011-02-18 12:40:47 -08004059 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004060 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004061 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004062 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004063 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004064 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004065 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004066 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004067 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004068 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
4069 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
4070 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004071 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004072 initTimes();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004073 mTrackBatteryPastUptime = 0;
4074 mTrackBatteryPastRealtime = 0;
4075 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4076 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4077 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4078 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07004079 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004080 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07004081 mDischargeCurrentLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004082 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004083 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004084 }
4085
4086 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004087 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004088 mHandler = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004089 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004090 readFromParcel(p);
4091 }
4092
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004093 public void setCallback(BatteryCallback cb) {
4094 mCallback = cb;
4095 }
4096
Amith Yamasanie43530a2009-08-21 13:11:37 -07004097 public void setNumSpeedSteps(int steps) {
4098 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
4099 }
4100
Amith Yamasanif37447b2009-10-08 18:28:01 -07004101 public void setRadioScanningTimeout(long timeout) {
4102 if (mPhoneSignalScanningTimer != null) {
4103 mPhoneSignalScanningTimer.setTimeout(timeout);
4104 }
4105 }
4106
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004107 @Override
4108 public boolean startIteratingOldHistoryLocked() {
4109 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4110 + " pos=" + mHistoryBuffer.dataPosition());
4111 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004112 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004113 mReadOverflow = false;
4114 mIteratingHistory = true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004115 return (mHistoryIterator = mHistory) != null;
4116 }
4117
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004118 @Override
4119 public boolean getNextOldHistoryLocked(HistoryItem out) {
4120 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
4121 if (!end) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004122 mHistoryReadTmp.readDelta(mHistoryBuffer);
4123 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004124 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004125 HistoryItem cur = mHistoryIterator;
4126 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004127 if (!mReadOverflow && !end) {
4128 Slog.w(TAG, "Old history ends before new history!");
4129 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004130 return false;
4131 }
4132 out.setTo(cur);
4133 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004134 if (!mReadOverflow) {
4135 if (end) {
4136 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004137 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004138 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
4139 PrintWriter pw = new PrintWriter(new LogWriter(android.util.Log.WARN, TAG));
4140 pw.println("Histories differ!");
4141 pw.println("Old history:");
4142 (new HistoryPrinter()).printNextItem(pw, out, now);
4143 pw.println("New history:");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004144 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004145 }
4146 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004147 return true;
4148 }
4149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004150 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004151 public void finishIteratingOldHistoryLocked() {
4152 mIteratingHistory = false;
4153 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
4154 }
4155
4156 @Override
4157 public boolean startIteratingHistoryLocked() {
4158 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4159 + " pos=" + mHistoryBuffer.dataPosition());
4160 mHistoryBuffer.setDataPosition(0);
4161 mReadOverflow = false;
4162 mIteratingHistory = true;
4163 return mHistoryBuffer.dataSize() > 0;
4164 }
4165
4166 @Override
4167 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004168 final int pos = mHistoryBuffer.dataPosition();
4169 if (pos == 0) {
4170 out.clear();
4171 }
4172 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004173 if (end) {
4174 return false;
4175 }
4176
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004177 out.readDelta(mHistoryBuffer);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004178 return true;
4179 }
4180
4181 @Override
4182 public void finishIteratingHistoryLocked() {
4183 mIteratingHistory = false;
4184 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004185 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004186
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004187 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004188 public long getHistoryBaseTime() {
4189 return mHistoryBaseTime;
4190 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004191
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004192 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004193 public int getStartCount() {
4194 return mStartCount;
4195 }
4196
4197 public boolean isOnBattery() {
4198 return mOnBattery;
4199 }
4200
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004201 public boolean isScreenOn() {
4202 return mScreenOn;
4203 }
4204
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004205 void initTimes() {
4206 mBatteryRealtime = mTrackBatteryPastUptime = 0;
4207 mBatteryUptime = mTrackBatteryPastRealtime = 0;
4208 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4209 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4210 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4211 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
4212 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004213
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004214 void initDischarge() {
4215 mLowDischargeAmountSinceCharge = 0;
4216 mHighDischargeAmountSinceCharge = 0;
4217 mDischargeAmountScreenOn = 0;
4218 mDischargeAmountScreenOnSinceCharge = 0;
4219 mDischargeAmountScreenOff = 0;
4220 mDischargeAmountScreenOffSinceCharge = 0;
4221 }
4222
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004223 public void resetAllStatsLocked() {
4224 mStartCount = 0;
4225 initTimes();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004226 mScreenOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004227 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004228 mScreenBrightnessTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004229 }
4230 mInputEventCounter.reset(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004231 mPhoneOnTimer.reset(this, false);
4232 mAudioOnTimer.reset(this, false);
4233 mVideoOnTimer.reset(this, false);
Wink Saville52840902011-02-18 12:40:47 -08004234 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004235 mPhoneSignalStrengthsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004236 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004237 mPhoneSignalScanningTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004238 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004239 mPhoneDataConnectionsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004240 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004241 mWifiOnTimer.reset(this, false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004242 mGlobalWifiRunningTimer.reset(this, false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004243 mBluetoothOnTimer.reset(this, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004244
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004245 for (int i=0; i<mUidStats.size(); i++) {
4246 if (mUidStats.valueAt(i).reset()) {
4247 mUidStats.remove(mUidStats.keyAt(i));
4248 i--;
4249 }
4250 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004251
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004252 if (mKernelWakelockStats.size() > 0) {
4253 for (SamplingTimer timer : mKernelWakelockStats.values()) {
4254 mUnpluggables.remove(timer);
4255 }
4256 mKernelWakelockStats.clear();
4257 }
4258
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004259 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004260
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004261 clearHistoryLocked();
4262 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004263
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004264 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004265 if (oldScreenOn) {
4266 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
4267 if (diff > 0) {
4268 mDischargeAmountScreenOn += diff;
4269 mDischargeAmountScreenOnSinceCharge += diff;
4270 }
4271 } else {
4272 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
4273 if (diff > 0) {
4274 mDischargeAmountScreenOff += diff;
4275 mDischargeAmountScreenOffSinceCharge += diff;
4276 }
4277 }
4278 if (newScreenOn) {
4279 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
4280 mDischargeScreenOffUnplugLevel = 0;
4281 } else {
4282 mDischargeScreenOnUnplugLevel = 0;
4283 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
4284 }
4285 }
4286
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004287 void setOnBattery(boolean onBattery, int oldStatus, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004288 synchronized(this) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004289 setOnBatteryLocked(onBattery, oldStatus, level);
4290 }
4291 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004292
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004293 void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
4294 boolean doWrite = false;
4295 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
4296 m.arg1 = onBattery ? 1 : 0;
4297 mHandler.sendMessage(m);
4298 mOnBattery = mOnBatteryInternal = onBattery;
4299
4300 long uptime = SystemClock.uptimeMillis() * 1000;
4301 long mSecRealtime = SystemClock.elapsedRealtime();
4302 long realtime = mSecRealtime * 1000;
4303 if (onBattery) {
4304 // We will reset our status if we are unplugging after the
4305 // battery was last full, or the level is at 100, or
4306 // we have gone through a significant charge (from a very low
4307 // level to a now very high level).
4308 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
4309 || level >= 90
4310 || (mDischargeCurrentLevel < 20 && level >= 80)) {
4311 doWrite = true;
4312 resetAllStatsLocked();
4313 mDischargeStartLevel = level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004314 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004315 updateKernelWakelocksLocked();
4316 mHistoryCur.batteryLevel = (byte)level;
4317 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4318 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
4319 + Integer.toHexString(mHistoryCur.states));
4320 addHistoryRecordLocked(mSecRealtime);
4321 mTrackBatteryUptimeStart = uptime;
4322 mTrackBatteryRealtimeStart = realtime;
4323 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
4324 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
4325 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
4326 if (mScreenOn) {
4327 mDischargeScreenOnUnplugLevel = level;
4328 mDischargeScreenOffUnplugLevel = 0;
4329 } else {
4330 mDischargeScreenOnUnplugLevel = 0;
4331 mDischargeScreenOffUnplugLevel = level;
4332 }
4333 mDischargeAmountScreenOn = 0;
4334 mDischargeAmountScreenOff = 0;
4335 doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
4336 } else {
4337 updateKernelWakelocksLocked();
4338 mHistoryCur.batteryLevel = (byte)level;
4339 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4340 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
4341 + Integer.toHexString(mHistoryCur.states));
4342 addHistoryRecordLocked(mSecRealtime);
4343 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
4344 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
4345 mDischargeCurrentLevel = level;
4346 if (level < mDischargeUnplugLevel) {
4347 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
4348 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
4349 }
4350 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
4351 doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
4352 }
4353 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
4354 if (mFile != null) {
4355 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004356 }
4357 }
4358 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004359
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004360 // This should probably be exposed in the API, though it's not critical
4361 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004362
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004363 public void setBatteryState(int status, int health, int plugType, int level,
4364 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004365 synchronized(this) {
4366 boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
4367 int oldStatus = mHistoryCur.batteryStatus;
4368 if (!mHaveBatteryLevel) {
4369 mHaveBatteryLevel = true;
4370 // We start out assuming that the device is plugged in (not
4371 // on battery). If our first report is now that we are indeed
4372 // plugged in, then twiddle our state to correctly reflect that
4373 // since we won't be going through the full setOnBattery().
4374 if (onBattery == mOnBattery) {
4375 if (onBattery) {
4376 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4377 } else {
4378 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4379 }
4380 }
4381 oldStatus = status;
4382 }
4383 if (onBattery) {
4384 mDischargeCurrentLevel = level;
4385 mRecordingHistory = true;
4386 }
4387 if (onBattery != mOnBattery) {
4388 mHistoryCur.batteryLevel = (byte)level;
4389 mHistoryCur.batteryStatus = (byte)status;
4390 mHistoryCur.batteryHealth = (byte)health;
4391 mHistoryCur.batteryPlugType = (byte)plugType;
4392 mHistoryCur.batteryTemperature = (char)temp;
4393 mHistoryCur.batteryVoltage = (char)volt;
4394 setOnBatteryLocked(onBattery, oldStatus, level);
4395 } else {
4396 boolean changed = false;
4397 if (mHistoryCur.batteryLevel != level) {
4398 mHistoryCur.batteryLevel = (byte)level;
4399 changed = true;
4400 }
4401 if (mHistoryCur.batteryStatus != status) {
4402 mHistoryCur.batteryStatus = (byte)status;
4403 changed = true;
4404 }
4405 if (mHistoryCur.batteryHealth != health) {
4406 mHistoryCur.batteryHealth = (byte)health;
4407 changed = true;
4408 }
4409 if (mHistoryCur.batteryPlugType != plugType) {
4410 mHistoryCur.batteryPlugType = (byte)plugType;
4411 changed = true;
4412 }
4413 if (temp >= (mHistoryCur.batteryTemperature+10)
4414 || temp <= (mHistoryCur.batteryTemperature-10)) {
4415 mHistoryCur.batteryTemperature = (char)temp;
4416 changed = true;
4417 }
4418 if (volt > (mHistoryCur.batteryVoltage+20)
4419 || volt < (mHistoryCur.batteryVoltage-20)) {
4420 mHistoryCur.batteryVoltage = (char)volt;
4421 changed = true;
4422 }
4423 if (changed) {
4424 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004425 }
4426 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004427 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
4428 // We don't record history while we are plugged in and fully charged.
4429 // The next time we are unplugged, history will be cleared.
4430 mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004431 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004432 }
Evan Millar633a1742009-04-02 16:36:33 -07004433 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004434
Evan Millarc64edde2009-04-18 12:26:32 -07004435 public void updateKernelWakelocksLocked() {
4436 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004437
Marco Nelissend8593312009-04-30 14:45:06 -07004438 if (m == null) {
4439 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004440 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07004441 return;
4442 }
4443
Evan Millarc64edde2009-04-18 12:26:32 -07004444 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
4445 String name = ent.getKey();
4446 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004447
Evan Millarc64edde2009-04-18 12:26:32 -07004448 SamplingTimer kwlt = mKernelWakelockStats.get(name);
4449 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004450 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07004451 true /* track reported values */);
4452 mKernelWakelockStats.put(name, kwlt);
4453 }
4454 kwlt.updateCurrentReportedCount(kws.mCount);
4455 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
4456 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
4457 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004458
Evan Millarc64edde2009-04-18 12:26:32 -07004459 if (m.size() != mKernelWakelockStats.size()) {
4460 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
4461 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4462 SamplingTimer st = ent.getValue();
4463 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
4464 st.setStale();
4465 }
4466 }
4467 }
4468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004469
4470 public long getAwakeTimeBattery() {
4471 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
4472 }
4473
4474 public long getAwakeTimePlugged() {
4475 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
4476 }
4477
4478 @Override
4479 public long computeUptime(long curTime, int which) {
4480 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004481 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 case STATS_LAST: return mLastUptime;
4483 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004484 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004485 }
4486 return 0;
4487 }
4488
4489 @Override
4490 public long computeRealtime(long curTime, int which) {
4491 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004492 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004493 case STATS_LAST: return mLastRealtime;
4494 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004495 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004496 }
4497 return 0;
4498 }
4499
4500 @Override
4501 public long computeBatteryUptime(long curTime, int which) {
4502 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004503 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004504 return mBatteryUptime + getBatteryUptime(curTime);
4505 case STATS_LAST:
4506 return mBatteryLastUptime;
4507 case STATS_CURRENT:
4508 return getBatteryUptime(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004509 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
4511 }
4512 return 0;
4513 }
4514
4515 @Override
4516 public long computeBatteryRealtime(long curTime, int which) {
4517 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004518 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
4520 case STATS_LAST:
4521 return mBatteryLastRealtime;
4522 case STATS_CURRENT:
4523 return getBatteryRealtimeLocked(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004524 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
4526 }
4527 return 0;
4528 }
4529
4530 long getBatteryUptimeLocked(long curTime) {
4531 long time = mTrackBatteryPastUptime;
4532 if (mOnBatteryInternal) {
4533 time += curTime - mTrackBatteryUptimeStart;
4534 }
4535 return time;
4536 }
4537
4538 long getBatteryUptimeLocked() {
4539 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
4540 }
4541
4542 @Override
4543 public long getBatteryUptime(long curTime) {
4544 return getBatteryUptimeLocked(curTime);
4545 }
4546
4547 long getBatteryRealtimeLocked(long curTime) {
4548 long time = mTrackBatteryPastRealtime;
4549 if (mOnBatteryInternal) {
4550 time += curTime - mTrackBatteryRealtimeStart;
4551 }
4552 return time;
4553 }
4554
4555 @Override
4556 public long getBatteryRealtime(long curTime) {
4557 return getBatteryRealtimeLocked(curTime);
4558 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004559
4560 private long getTcpBytes(long current, long[] dataBytes, int which) {
4561 if (which == STATS_LAST) {
4562 return dataBytes[STATS_LAST];
4563 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004564 if (which == STATS_SINCE_UNPLUGGED) {
4565 if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004566 return dataBytes[STATS_LAST];
4567 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004568 return current - dataBytes[STATS_SINCE_UNPLUGGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004569 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004570 } else if (which == STATS_SINCE_CHARGED) {
4571 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004572 }
4573 return current - dataBytes[STATS_CURRENT];
4574 }
4575 }
4576
4577 /** Only STATS_UNPLUGGED works properly */
4578 public long getMobileTcpBytesSent(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004579 final long mobileTxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).txBytes;
4580 return getTcpBytes(mobileTxBytes, mMobileDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004581 }
4582
4583 /** Only STATS_UNPLUGGED works properly */
4584 public long getMobileTcpBytesReceived(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004585 final long mobileRxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).rxBytes;
4586 return getTcpBytes(mobileRxBytes, mMobileDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004587 }
4588
4589 /** Only STATS_UNPLUGGED works properly */
4590 public long getTotalTcpBytesSent(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004591 final long totalTxBytes = getNetworkStatsSummary().getTotal(null).txBytes;
4592 return getTcpBytes(totalTxBytes, mTotalDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004593 }
4594
4595 /** Only STATS_UNPLUGGED works properly */
4596 public long getTotalTcpBytesReceived(int which) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004597 final long totalRxBytes = getNetworkStatsSummary().getTotal(null).rxBytes;
4598 return getTcpBytes(totalRxBytes, mTotalDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004599 }
4600
The Android Open Source Project10592532009-03-18 17:39:46 -07004601 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004602 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004603 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004604 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004605 }
4606 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004607
Evan Millar633a1742009-04-02 16:36:33 -07004608 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004609 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004610 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004611
The Android Open Source Project10592532009-03-18 17:39:46 -07004612 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004613 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004614 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004615 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004616 }
4617 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004618
Evan Millar633a1742009-04-02 16:36:33 -07004619 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004620 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622
Amith Yamasanie43530a2009-08-21 13:11:37 -07004623 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004624 public int getLowDischargeAmountSinceCharge() {
4625 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004626 int val = mLowDischargeAmountSinceCharge;
4627 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4628 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
4629 }
4630 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004631 }
4632 }
4633
4634 @Override
4635 public int getHighDischargeAmountSinceCharge() {
4636 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004637 int val = mHighDischargeAmountSinceCharge;
4638 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4639 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
4640 }
4641 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004642 }
4643 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004644
4645 public int getDischargeAmountScreenOn() {
4646 synchronized(this) {
4647 int val = mDischargeAmountScreenOn;
4648 if (mOnBattery && mScreenOn
4649 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4650 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4651 }
4652 return val;
4653 }
4654 }
4655
4656 public int getDischargeAmountScreenOnSinceCharge() {
4657 synchronized(this) {
4658 int val = mDischargeAmountScreenOnSinceCharge;
4659 if (mOnBattery && mScreenOn
4660 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4661 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4662 }
4663 return val;
4664 }
4665 }
4666
4667 public int getDischargeAmountScreenOff() {
4668 synchronized(this) {
4669 int val = mDischargeAmountScreenOff;
4670 if (mOnBattery && !mScreenOn
4671 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4672 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4673 }
4674 return val;
4675 }
4676 }
4677
4678 public int getDischargeAmountScreenOffSinceCharge() {
4679 synchronized(this) {
4680 int val = mDischargeAmountScreenOffSinceCharge;
4681 if (mOnBattery && !mScreenOn
4682 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
4683 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
4684 }
4685 return val;
4686 }
4687 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004688
4689 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07004690 public int getCpuSpeedSteps() {
4691 return sNumSpeedSteps;
4692 }
4693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004694 /**
4695 * Retrieve the statistics object for a particular uid, creating if needed.
4696 */
4697 public Uid getUidStatsLocked(int uid) {
4698 Uid u = mUidStats.get(uid);
4699 if (u == null) {
4700 u = new Uid(uid);
4701 mUidStats.put(uid, u);
4702 }
4703 return u;
4704 }
4705
4706 /**
4707 * Remove the statistics object for a particular uid.
4708 */
4709 public void removeUidStatsLocked(int uid) {
4710 mUidStats.remove(uid);
4711 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004713 /**
4714 * Retrieve the statistics object for a particular process, creating
4715 * if needed.
4716 */
4717 public Uid.Proc getProcessStatsLocked(int uid, String name) {
4718 Uid u = getUidStatsLocked(uid);
4719 return u.getProcessStatsLocked(name);
4720 }
4721
4722 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004723 * Retrieve the statistics object for a particular process, given
4724 * the name of the process.
4725 * @param name process name
4726 * @return the statistics object for the process
4727 */
Amith Yamasani819f9282009-06-24 23:18:15 -07004728 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004729 int uid;
4730 if (mUidCache.containsKey(name)) {
4731 uid = mUidCache.get(name);
4732 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07004733 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004734 mUidCache.put(name, uid);
4735 }
4736 Uid u = getUidStatsLocked(uid);
4737 return u.getProcessStatsLocked(name);
4738 }
4739
4740 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 * Retrieve the statistics object for a particular process, creating
4742 * if needed.
4743 */
4744 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
4745 Uid u = getUidStatsLocked(uid);
4746 return u.getPackageStatsLocked(pkg);
4747 }
4748
4749 /**
4750 * Retrieve the statistics object for a particular service, creating
4751 * if needed.
4752 */
4753 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
4754 Uid u = getUidStatsLocked(uid);
4755 return u.getServiceStatsLocked(pkg, name);
4756 }
4757
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004758 /**
4759 * Massage data to distribute any reasonable work down to more specific
4760 * owners. Must only be called on a dead BatteryStats object!
4761 */
4762 public void distributeWorkLocked(int which) {
4763 // Aggregate all CPU time associated with WIFI.
4764 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
4765 if (wifiUid != null) {
4766 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
4767 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
4768 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
4769 for (int i=0; i<mUidStats.size(); i++) {
4770 Uid uid = mUidStats.valueAt(i);
4771 if (uid.mUid != Process.WIFI_UID) {
4772 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
4773 if (uidRunningTime > 0) {
4774 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
4775 long time = proc.getUserTime(which);
4776 time = (time*uidRunningTime)/totalRunningTime;
4777 uidProc.mUserTime += time;
4778 proc.mUserTime -= time;
4779 time = proc.getSystemTime(which);
4780 time = (time*uidRunningTime)/totalRunningTime;
4781 uidProc.mSystemTime += time;
4782 proc.mSystemTime -= time;
4783 time = proc.getForegroundTime(which);
4784 time = (time*uidRunningTime)/totalRunningTime;
4785 uidProc.mForegroundTime += time;
4786 proc.mForegroundTime -= time;
4787 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
4788 SamplingCounter sc = proc.mSpeedBins[sb];
4789 if (sc != null) {
4790 time = sc.getCountLocked(which);
4791 time = (time*uidRunningTime)/totalRunningTime;
4792 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
4793 if (uidSc == null) {
4794 uidSc = new SamplingCounter(mUnpluggables);
4795 uidProc.mSpeedBins[sb] = uidSc;
4796 }
4797 uidSc.mCount.addAndGet((int)time);
4798 sc.mCount.addAndGet((int)-time);
4799 }
4800 }
4801 totalRunningTime -= uidRunningTime;
4802 }
4803 }
4804 }
4805 }
4806 }
4807 }
4808
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004809 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004810 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004811 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004812 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004813
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004814 Parcel mPendingWrite = null;
4815 final ReentrantLock mWriteLock = new ReentrantLock();
4816
4817 public void writeAsyncLocked() {
4818 writeLocked(false);
4819 }
4820
4821 public void writeSyncLocked() {
4822 writeLocked(true);
4823 }
4824
4825 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004826 if (mFile == null) {
4827 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004828 return;
4829 }
4830
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004831 if (mShuttingDown) {
4832 return;
4833 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004834
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004835 Parcel out = Parcel.obtain();
4836 writeSummaryToParcel(out);
4837 mLastWriteTime = SystemClock.elapsedRealtime();
4838
4839 if (mPendingWrite != null) {
4840 mPendingWrite.recycle();
4841 }
4842 mPendingWrite = out;
4843
4844 if (sync) {
4845 commitPendingDataToDisk();
4846 } else {
4847 Thread thr = new Thread("BatteryStats-Write") {
4848 @Override
4849 public void run() {
4850 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
4851 commitPendingDataToDisk();
4852 }
4853 };
4854 thr.start();
4855 }
4856 }
4857
4858 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004859 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004860 synchronized (this) {
4861 next = mPendingWrite;
4862 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07004863 if (next == null) {
4864 return;
4865 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004866
4867 mWriteLock.lock();
4868 }
4869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004871 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004872 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004873 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07004874 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004875 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004876 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004877 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004878 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004879 mFile.rollback();
4880 } finally {
4881 next.recycle();
4882 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07004883 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004884 }
4885
4886 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
4887 int pos = 0;
4888 int avail = stream.available();
4889 byte[] data = new byte[avail];
4890 while (true) {
4891 int amt = stream.read(data, pos, data.length-pos);
4892 //Log.i("foo", "Read " + amt + " bytes at " + pos
4893 // + " of avail " + data.length);
4894 if (amt <= 0) {
4895 //Log.i("foo", "**** FINISHED READING: pos=" + pos
4896 // + " len=" + data.length);
4897 return data;
4898 }
4899 pos += amt;
4900 avail = stream.available();
4901 if (avail > data.length-pos) {
4902 byte[] newData = new byte[pos+avail];
4903 System.arraycopy(data, 0, newData, 0, pos);
4904 data = newData;
4905 }
4906 }
4907 }
4908
4909 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004910 if (mFile == null) {
4911 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004912 return;
4913 }
4914
4915 mUidStats.clear();
4916
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004917 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004918 File file = mFile.chooseForRead();
4919 if (!file.exists()) {
4920 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004921 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004922 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004923
4924 byte[] raw = readFully(stream);
4925 Parcel in = Parcel.obtain();
4926 in.unmarshall(raw, 0, raw.length);
4927 in.setDataPosition(0);
4928 stream.close();
4929
4930 readSummaryFromParcel(in);
4931 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004932 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004934
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004935 long now = SystemClock.elapsedRealtime();
Dianne Hackborne8c88e62011-08-17 19:09:09 -07004936 if (USE_OLD_HISTORY) {
4937 addHistoryRecordLocked(now, HistoryItem.CMD_START);
4938 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004939 addHistoryBufferLocked(now, HistoryItem.CMD_START);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004940 }
4941
4942 public int describeContents() {
4943 return 0;
4944 }
4945
Dianne Hackbornae384452011-06-28 12:33:48 -07004946 void readHistory(Parcel in, boolean andOldHistory) {
4947 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004948
4949 mHistoryBuffer.setDataSize(0);
4950 mHistoryBuffer.setDataPosition(0);
4951
4952 int bufSize = in.readInt();
4953 int curPos = in.dataPosition();
4954 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
4955 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
4956 } else if ((bufSize&~3) != bufSize) {
4957 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
4958 } else {
4959 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
4960 + " bytes at " + curPos);
4961 mHistoryBuffer.appendFrom(in, curPos, bufSize);
4962 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004963 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004964
Dianne Hackbornae384452011-06-28 12:33:48 -07004965 if (andOldHistory) {
4966 readOldHistory(in);
4967 }
4968
4969 if (DEBUG_HISTORY) {
4970 StringBuilder sb = new StringBuilder(128);
4971 sb.append("****************** OLD mHistoryBaseTime: ");
4972 TimeUtils.formatDuration(mHistoryBaseTime, sb);
4973 Slog.i(TAG, sb.toString());
4974 }
4975 mHistoryBaseTime = historyBaseTime;
4976 if (DEBUG_HISTORY) {
4977 StringBuilder sb = new StringBuilder(128);
4978 sb.append("****************** NEW mHistoryBaseTime: ");
4979 TimeUtils.formatDuration(mHistoryBaseTime, sb);
4980 Slog.i(TAG, sb.toString());
4981 }
4982
4983 // We are just arbitrarily going to insert 1 minute from the sample of
4984 // the last run until samples in this run.
4985 if (mHistoryBaseTime > 0) {
4986 long oldnow = SystemClock.elapsedRealtime();
4987 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000;
4988 if (DEBUG_HISTORY) {
4989 StringBuilder sb = new StringBuilder(128);
4990 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
4991 TimeUtils.formatDuration(mHistoryBaseTime, sb);
4992 Slog.i(TAG, sb.toString());
4993 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07004994 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004995 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004996
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004997 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07004998 if (!USE_OLD_HISTORY) {
4999 return;
5000 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005001 mHistory = mHistoryEnd = mHistoryCache = null;
5002 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07005003 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005004 HistoryItem rec = new HistoryItem(time, in);
5005 addHistoryRecordLocked(rec);
5006 }
5007 }
5008
Dianne Hackbornae384452011-06-28 12:33:48 -07005009 void writeHistory(Parcel out, boolean andOldHistory) {
5010 if (DEBUG_HISTORY) {
5011 StringBuilder sb = new StringBuilder(128);
5012 sb.append("****************** WRITING mHistoryBaseTime: ");
5013 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5014 sb.append(" mLastHistoryTime: ");
5015 TimeUtils.formatDuration(mLastHistoryTime, sb);
5016 Slog.i(TAG, sb.toString());
5017 }
5018 out.writeLong(mHistoryBaseTime + mLastHistoryTime);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005019 out.writeInt(mHistoryBuffer.dataSize());
5020 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
5021 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
5022 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07005023
5024 if (andOldHistory) {
5025 writeOldHistory(out);
5026 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005027 }
5028
5029 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005030 if (!USE_OLD_HISTORY) {
5031 return;
5032 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005033 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005034 while (rec != null) {
5035 if (rec.time >= 0) rec.writeToParcel(out, 0);
5036 rec = rec.next;
5037 }
5038 out.writeLong(-1);
5039 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 private void readSummaryFromParcel(Parcel in) {
5042 final int version = in.readInt();
5043 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005044 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045 + ", expected " + VERSION + "; erasing old stats");
5046 return;
5047 }
5048
Dianne Hackbornae384452011-06-28 12:33:48 -07005049 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005051 mStartCount = in.readInt();
5052 mBatteryUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005053 mBatteryRealtime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005054 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005055 mRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005056 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005057 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005058 mLowDischargeAmountSinceCharge = in.readInt();
5059 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005060 mDischargeAmountScreenOnSinceCharge = in.readInt();
5061 mDischargeAmountScreenOffSinceCharge = in.readInt();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005063 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005065 mScreenOn = false;
5066 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005067 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5068 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
5069 }
5070 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005071 mPhoneOn = false;
5072 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08005073 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005074 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
5075 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005076 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005077 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5078 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
5079 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005080 mWifiOn = false;
5081 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005082 mGlobalWifiRunning = false;
5083 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005084 mBluetoothOn = false;
5085 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005086
Evan Millarc64edde2009-04-18 12:26:32 -07005087 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005088 if (NKW > 10000) {
5089 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
5090 return;
5091 }
Evan Millarc64edde2009-04-18 12:26:32 -07005092 for (int ikw = 0; ikw < NKW; ikw++) {
5093 if (in.readInt() != 0) {
5094 String kwltName = in.readString();
5095 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
5096 }
5097 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005098
5099 sNumSpeedSteps = in.readInt();
5100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005101 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005102 if (NU > 10000) {
5103 Slog.w(TAG, "File corrupt: too many uids " + NU);
5104 return;
5105 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005106 for (int iu = 0; iu < NU; iu++) {
5107 int uid = in.readInt();
5108 Uid u = new Uid(uid);
5109 mUidStats.put(uid, u);
5110
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005111 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005112 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005113 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005114 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005115 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005116 if (in.readInt() != 0) {
5117 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
5118 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005119 u.mScanWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005120 if (in.readInt() != 0) {
5121 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
5122 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005123 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005124 if (in.readInt() != 0) {
5125 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
5126 }
5127 u.mAudioTurnedOn = false;
5128 if (in.readInt() != 0) {
5129 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
5130 }
5131 u.mVideoTurnedOn = false;
5132 if (in.readInt() != 0) {
5133 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
5134 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005135
Dianne Hackborn617f8772009-03-31 15:04:46 -07005136 if (in.readInt() != 0) {
5137 if (u.mUserActivityCounters == null) {
5138 u.initUserActivityLocked();
5139 }
5140 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5141 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
5142 }
5143 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005145 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005146 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005147 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
5148 return;
5149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005150 for (int iw = 0; iw < NW; iw++) {
5151 String wlName = in.readString();
5152 if (in.readInt() != 0) {
5153 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
5154 }
5155 if (in.readInt() != 0) {
5156 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
5157 }
5158 if (in.readInt() != 0) {
5159 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
5160 }
5161 }
5162
5163 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005164 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005165 Slog.w(TAG, "File corrupt: too many sensors " + NP);
5166 return;
5167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005168 for (int is = 0; is < NP; is++) {
5169 int seNumber = in.readInt();
5170 if (in.readInt() != 0) {
5171 u.getSensorTimerLocked(seNumber, true)
5172 .readSummaryFromParcelLocked(in);
5173 }
5174 }
5175
5176 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005177 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005178 Slog.w(TAG, "File corrupt: too many processes " + NP);
5179 return;
5180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 for (int ip = 0; ip < NP; ip++) {
5182 String procName = in.readString();
5183 Uid.Proc p = u.getProcessStatsLocked(procName);
5184 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005185 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005186 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005187 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005188 if (NSB > 100) {
5189 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
5190 return;
5191 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005192 p.mSpeedBins = new SamplingCounter[NSB];
5193 for (int i=0; i<NSB; i++) {
5194 if (in.readInt() != 0) {
5195 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables);
5196 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
5197 }
5198 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005199 if (!p.readExcessivePowerFromParcelLocked(in)) {
5200 return;
5201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005202 }
5203
5204 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005205 if (NP > 10000) {
5206 Slog.w(TAG, "File corrupt: too many packages " + NP);
5207 return;
5208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005209 for (int ip = 0; ip < NP; ip++) {
5210 String pkgName = in.readString();
5211 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
5212 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005214 if (NS > 1000) {
5215 Slog.w(TAG, "File corrupt: too many services " + NS);
5216 return;
5217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 for (int is = 0; is < NS; is++) {
5219 String servName = in.readString();
5220 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
5221 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005222 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005223 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005224 }
5225 }
5226
5227 u.mLoadedTcpBytesReceived = in.readLong();
5228 u.mLoadedTcpBytesSent = in.readLong();
5229 }
5230 }
5231
5232 /**
5233 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
5234 * disk. This format does not allow a lossless round-trip.
5235 *
5236 * @param out the Parcel to be written to.
5237 */
5238 public void writeSummaryToParcel(Parcel out) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005239 // Need to update with current kernel wake lock counts.
5240 updateKernelWakelocksLocked();
5241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005242 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
5243 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
5244 final long NOW = getBatteryUptimeLocked(NOW_SYS);
5245 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
5246
5247 out.writeInt(VERSION);
5248
Dianne Hackbornae384452011-06-28 12:33:48 -07005249 writeHistory(out, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005251 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005252 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005253 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005254 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005255 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005256 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005257 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08005258 out.writeInt(getLowDischargeAmountSinceCharge());
5259 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005260 out.writeInt(getDischargeAmountScreenOnSinceCharge());
5261 out.writeInt(getDischargeAmountScreenOffSinceCharge());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005262
5263 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005264 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5265 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5266 }
5267 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005268 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Wink Saville52840902011-02-18 12:40:47 -08005269 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005270 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5271 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005272 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005273 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5274 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5275 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005276 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005277 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07005278 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005279
Evan Millarc64edde2009-04-18 12:26:32 -07005280 out.writeInt(mKernelWakelockStats.size());
5281 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5282 Timer kwlt = ent.getValue();
5283 if (kwlt != null) {
5284 out.writeInt(1);
5285 out.writeString(ent.getKey());
5286 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
5287 } else {
5288 out.writeInt(0);
5289 }
5290 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005291
Amith Yamasanie43530a2009-08-21 13:11:37 -07005292 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005293 final int NU = mUidStats.size();
5294 out.writeInt(NU);
5295 for (int iu = 0; iu < NU; iu++) {
5296 out.writeInt(mUidStats.keyAt(iu));
5297 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005298
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005299 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005300 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005301 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005302 } else {
5303 out.writeInt(0);
5304 }
5305 if (u.mFullWifiLockTimer != null) {
5306 out.writeInt(1);
5307 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5308 } else {
5309 out.writeInt(0);
5310 }
5311 if (u.mScanWifiLockTimer != null) {
5312 out.writeInt(1);
5313 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5314 } else {
5315 out.writeInt(0);
5316 }
5317 if (u.mWifiMulticastTimer != null) {
5318 out.writeInt(1);
5319 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5320 } else {
5321 out.writeInt(0);
5322 }
5323 if (u.mAudioTurnedOnTimer != null) {
5324 out.writeInt(1);
5325 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5326 } else {
5327 out.writeInt(0);
5328 }
5329 if (u.mVideoTurnedOnTimer != null) {
5330 out.writeInt(1);
5331 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5332 } else {
5333 out.writeInt(0);
5334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005335
Dianne Hackborn617f8772009-03-31 15:04:46 -07005336 if (u.mUserActivityCounters == null) {
5337 out.writeInt(0);
5338 } else {
5339 out.writeInt(1);
5340 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5341 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
5342 }
5343 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005345 int NW = u.mWakelockStats.size();
5346 out.writeInt(NW);
5347 if (NW > 0) {
5348 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
5349 : u.mWakelockStats.entrySet()) {
5350 out.writeString(ent.getKey());
5351 Uid.Wakelock wl = ent.getValue();
5352 if (wl.mTimerFull != null) {
5353 out.writeInt(1);
5354 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
5355 } else {
5356 out.writeInt(0);
5357 }
5358 if (wl.mTimerPartial != null) {
5359 out.writeInt(1);
5360 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
5361 } else {
5362 out.writeInt(0);
5363 }
5364 if (wl.mTimerWindow != null) {
5365 out.writeInt(1);
5366 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
5367 } else {
5368 out.writeInt(0);
5369 }
5370 }
5371 }
5372
5373 int NSE = u.mSensorStats.size();
5374 out.writeInt(NSE);
5375 if (NSE > 0) {
5376 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
5377 : u.mSensorStats.entrySet()) {
5378 out.writeInt(ent.getKey());
5379 Uid.Sensor se = ent.getValue();
5380 if (se.mTimer != null) {
5381 out.writeInt(1);
5382 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5383 } else {
5384 out.writeInt(0);
5385 }
5386 }
5387 }
5388
5389 int NP = u.mProcessStats.size();
5390 out.writeInt(NP);
5391 if (NP > 0) {
5392 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
5393 : u.mProcessStats.entrySet()) {
5394 out.writeString(ent.getKey());
5395 Uid.Proc ps = ent.getValue();
5396 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005397 out.writeLong(ps.mSystemTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005398 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005399 final int N = ps.mSpeedBins.length;
5400 out.writeInt(N);
5401 for (int i=0; i<N; i++) {
5402 if (ps.mSpeedBins[i] != null) {
5403 out.writeInt(1);
5404 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
5405 } else {
5406 out.writeInt(0);
5407 }
5408 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005409 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 }
5411 }
5412
5413 NP = u.mPackageStats.size();
5414 out.writeInt(NP);
5415 if (NP > 0) {
5416 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
5417 : u.mPackageStats.entrySet()) {
5418 out.writeString(ent.getKey());
5419 Uid.Pkg ps = ent.getValue();
5420 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005421 final int NS = ps.mServiceStats.size();
5422 out.writeInt(NS);
5423 if (NS > 0) {
5424 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
5425 : ps.mServiceStats.entrySet()) {
5426 out.writeString(sent.getKey());
5427 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
5428 long time = ss.getStartTimeToNowLocked(NOW);
5429 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005430 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005431 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 }
5433 }
5434 }
5435 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005436
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005437 out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED));
5438 out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005439 }
5440 }
5441
5442 public void readFromParcel(Parcel in) {
5443 readFromParcelLocked(in);
5444 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 void readFromParcelLocked(Parcel in) {
5447 int magic = in.readInt();
5448 if (magic != MAGIC) {
5449 throw new ParcelFormatException("Bad magic number");
5450 }
5451
Dianne Hackbornae384452011-06-28 12:33:48 -07005452 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005454 mStartCount = in.readInt();
5455 mBatteryUptime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005456 mBatteryLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005457 mBatteryRealtime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005458 mBatteryLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005459 mScreenOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005460 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005461 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005462 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i,
5463 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005464 }
5465 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 mPhoneOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005467 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Wink Saville52840902011-02-18 12:40:47 -08005468 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005469 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
5470 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005471 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005472 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005473 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005474 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
5475 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005476 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005477 mWifiOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005478 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005479 mGlobalWifiRunning = false;
5480 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005481 mBluetoothOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005482 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005483 mUptime = in.readLong();
5484 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005485 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005486 mRealtime = in.readLong();
5487 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005488 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005489 mOnBattery = in.readInt() != 0;
5490 mOnBatteryInternal = false; // we are no longer really running.
5491 mTrackBatteryPastUptime = in.readLong();
5492 mTrackBatteryUptimeStart = in.readLong();
5493 mTrackBatteryPastRealtime = in.readLong();
5494 mTrackBatteryRealtimeStart = in.readLong();
5495 mUnpluggedBatteryUptime = in.readLong();
5496 mUnpluggedBatteryRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005497 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005498 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005499 mLowDischargeAmountSinceCharge = in.readInt();
5500 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005501 mDischargeAmountScreenOn = in.readInt();
5502 mDischargeAmountScreenOnSinceCharge = in.readInt();
5503 mDischargeAmountScreenOff = in.readInt();
5504 mDischargeAmountScreenOffSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005505 mLastWriteTime = in.readLong();
5506
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005507 mMobileDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005508 mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005509 mMobileDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005510 mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005511 mTotalDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005512 mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005513 mTotalDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005514 mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005515
5516 mRadioDataUptime = in.readLong();
5517 mRadioDataStart = -1;
5518
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005519 mBluetoothPingCount = in.readInt();
5520 mBluetoothPingStart = -1;
5521
Evan Millarc64edde2009-04-18 12:26:32 -07005522 mKernelWakelockStats.clear();
5523 int NKW = in.readInt();
5524 for (int ikw = 0; ikw < NKW; ikw++) {
5525 if (in.readInt() != 0) {
5526 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005527 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07005528 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
5529 mKernelWakelockStats.put(wakelockName, kwlt);
5530 }
5531 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 mPartialTimers.clear();
5534 mFullTimers.clear();
5535 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005536 mWifiRunningTimers.clear();
5537 mFullWifiLockTimers.clear();
5538 mScanWifiLockTimers.clear();
5539 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005540
Amith Yamasanie43530a2009-08-21 13:11:37 -07005541 sNumSpeedSteps = in.readInt();
5542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005543 int numUids = in.readInt();
5544 mUidStats.clear();
5545 for (int i = 0; i < numUids; i++) {
5546 int uid = in.readInt();
5547 Uid u = new Uid(uid);
5548 u.readFromParcelLocked(mUnpluggables, in);
5549 mUidStats.append(uid, u);
5550 }
5551 }
5552
5553 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005554 writeToParcelLocked(out, true, flags);
5555 }
5556
5557 public void writeToParcelWithoutUids(Parcel out, int flags) {
5558 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005559 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005560
5561 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005562 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005563 // Need to update with current kernel wake lock counts.
5564 updateKernelWakelocksLocked();
5565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005566 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
5567 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
5568 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
5569 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005571 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005572
Dianne Hackbornae384452011-06-28 12:33:48 -07005573 writeHistory(out, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005575 out.writeInt(mStartCount);
5576 out.writeLong(mBatteryUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005577 out.writeLong(mBatteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005578 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005579 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5580 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
5581 }
5582 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005583 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Wink Saville52840902011-02-18 12:40:47 -08005584 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005585 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
5586 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005587 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005588 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5589 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
5590 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005591 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005592 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005593 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005594 out.writeLong(mUptime);
5595 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005596 out.writeLong(mRealtime);
5597 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005598 out.writeInt(mOnBattery ? 1 : 0);
5599 out.writeLong(batteryUptime);
5600 out.writeLong(mTrackBatteryUptimeStart);
5601 out.writeLong(batteryRealtime);
5602 out.writeLong(mTrackBatteryRealtimeStart);
5603 out.writeLong(mUnpluggedBatteryUptime);
5604 out.writeLong(mUnpluggedBatteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005605 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005606 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005607 out.writeInt(mLowDischargeAmountSinceCharge);
5608 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005609 out.writeInt(mDischargeAmountScreenOn);
5610 out.writeInt(mDischargeAmountScreenOnSinceCharge);
5611 out.writeInt(mDischargeAmountScreenOff);
5612 out.writeInt(mDischargeAmountScreenOffSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005613 out.writeLong(mLastWriteTime);
5614
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005615 out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5616 out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED));
5617 out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED));
5618 out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED));
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005619
5620 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005621 out.writeLong(getRadioDataUptime());
5622
5623 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005624
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005625 if (inclUids) {
5626 out.writeInt(mKernelWakelockStats.size());
5627 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5628 SamplingTimer kwlt = ent.getValue();
5629 if (kwlt != null) {
5630 out.writeInt(1);
5631 out.writeString(ent.getKey());
5632 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
5633 } else {
5634 out.writeInt(0);
5635 }
Evan Millarc64edde2009-04-18 12:26:32 -07005636 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005637 } else {
5638 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07005639 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005640
5641 out.writeInt(sNumSpeedSteps);
5642
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005643 if (inclUids) {
5644 int size = mUidStats.size();
5645 out.writeInt(size);
5646 for (int i = 0; i < size; i++) {
5647 out.writeInt(mUidStats.keyAt(i));
5648 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005649
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005650 uid.writeToParcelLocked(out, batteryRealtime);
5651 }
5652 } else {
5653 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005654 }
5655 }
5656
5657 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
5658 new Parcelable.Creator<BatteryStatsImpl>() {
5659 public BatteryStatsImpl createFromParcel(Parcel in) {
5660 return new BatteryStatsImpl(in);
5661 }
5662
5663 public BatteryStatsImpl[] newArray(int size) {
5664 return new BatteryStatsImpl[size];
5665 }
5666 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005667
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005668 public void prepareForDumpLocked() {
5669 // Need to retrieve current kernel wake lock stats before printing.
5670 updateKernelWakelocksLocked();
5671 }
5672
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005673 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005674 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005675 Printer pr = new PrintWriterPrinter(pw);
5676 pr.println("*** Screen timer:");
5677 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005678 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005679 pr.println("*** Screen brightness #" + i + ":");
5680 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07005681 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005682 pr.println("*** Input event counter:");
5683 mInputEventCounter.logState(pr, " ");
5684 pr.println("*** Phone timer:");
5685 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08005686 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005687 pr.println("*** Signal strength #" + i + ":");
5688 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005689 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005690 pr.println("*** Signal scanning :");
5691 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005692 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005693 pr.println("*** Data connection type #" + i + ":");
5694 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07005695 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005696 pr.println("*** Wifi timer:");
5697 mWifiOnTimer.logState(pr, " ");
5698 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005699 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07005700 pr.println("*** Bluetooth timer:");
5701 mBluetoothOnTimer.logState(pr, " ");
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005702 pr.println("*** Mobile ifaces:");
5703 pr.println(mMobileIfaces.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005704 }
5705 super.dumpLocked(pw);
5706 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005707
5708 private NetworkStats mNetworkSummaryCache;
5709 private NetworkStats mNetworkDetailCache;
5710
5711 private NetworkStats getNetworkStatsSummary() {
5712 // NOTE: calls from BatteryStatsService already hold this lock
5713 synchronized (this) {
5714 if (mNetworkSummaryCache == null
5715 || mNetworkSummaryCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) {
5716 try {
5717 mNetworkSummaryCache = mNetworkStatsFactory.readNetworkStatsSummary();
5718 } catch (IllegalStateException e) {
5719 // log problem and return empty object
5720 Log.wtf(TAG, "problem reading network stats", e);
5721 mNetworkSummaryCache = new NetworkStats(SystemClock.elapsedRealtime(), 0);
5722 }
5723 }
5724 return mNetworkSummaryCache;
5725 }
5726 }
5727
5728 private NetworkStats getNetworkStatsDetailGroupedByUid() {
5729 // NOTE: calls from BatteryStatsService already hold this lock
5730 synchronized (this) {
5731 if (mNetworkDetailCache == null
5732 || mNetworkDetailCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) {
5733 try {
5734 mNetworkDetailCache = mNetworkStatsFactory
5735 .readNetworkStatsDetail().groupedByUid();
5736 } catch (IllegalStateException e) {
5737 // log problem and return empty object
5738 Log.wtf(TAG, "problem reading network stats", e);
5739 mNetworkDetailCache = new NetworkStats(SystemClock.elapsedRealtime(), 0);
5740 }
5741 }
5742 return mNetworkDetailCache;
5743 }
5744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005745}