blob: e0a154cea29ace9784ffe8a208a617f3110218b0 [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 Sharkey418d12d2011-12-13 15:38:03 -080019import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070020
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070021import android.bluetooth.BluetoothDevice;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070022import android.bluetooth.BluetoothHeadset;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070023import android.net.ConnectivityManager;
24import android.net.NetworkStats;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070025import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.os.BatteryStats;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070027import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070028import android.os.Handler;
29import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.os.Parcel;
31import android.os.ParcelFormatException;
32import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070033import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.os.SystemClock;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080035import android.os.SystemProperties;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070036import android.os.WorkSource;
Amith Yamasanif37447b2009-10-08 18:28:01 -070037import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070038import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070039import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070041import android.util.LogWriter;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070042import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070044import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.util.SparseArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070046import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070048import com.android.internal.annotations.GuardedBy;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070049import com.android.internal.net.NetworkStatsFactory;
Dianne Hackborn8c841092013-06-24 13:46:13 -070050import com.android.internal.util.FastPrintWriter;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070051import com.android.internal.util.JournaledFile;
52import com.google.android.collect.Sets;
53
Amith Yamasani3718aaa2009-06-09 06:32:35 -070054import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import java.io.File;
56import java.io.FileInputStream;
57import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070058import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070060import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import java.util.ArrayList;
62import java.util.HashMap;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070063import java.util.HashSet;
Evan Millarc64edde2009-04-18 12:26:32 -070064import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070065import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070067import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070068import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
70/**
71 * All information we are collecting about things that can happen that impact
72 * battery life. All times are represented in microseconds except where indicated
73 * otherwise.
74 */
75public final class BatteryStatsImpl extends BatteryStats {
76 private static final String TAG = "BatteryStatsImpl";
77 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070078 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -070079 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070080
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070081 // TODO: remove "tcp" from network methods, since we measure total stats.
82
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070084 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085
86 // Current on-disk Parcel version
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070087 private static final int VERSION = 66 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -070088
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070089 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070090 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070091
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070092 // No, really, THIS is the maximum number of items we will record in the history.
93 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
94
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080095 // The maximum number of names wakelocks we will keep track of
96 // per uid; once the limit is reached, we batch the remaining wakelocks
97 // in to one common name.
Dianne Hackbornaf17baa2013-05-09 15:27:47 -070098 private static final int MAX_WAKELOCKS_PER_UID = 50;
Dianne Hackbornc24ab862011-10-18 15:55:03 -070099
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800100 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700101
Amith Yamasanie43530a2009-08-21 13:11:37 -0700102 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700104 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700106 static final int MSG_UPDATE_WAKELOCKS = 1;
107 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700108 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700109
110 public interface BatteryCallback {
111 public void batteryNeedsCpuUpdate();
112 public void batteryPowerChanged(boolean onBattery);
113 }
114
115 final class MyHandler extends Handler {
116 @Override
117 public void handleMessage(Message msg) {
118 BatteryCallback cb = mCallback;
119 switch (msg.what) {
120 case MSG_UPDATE_WAKELOCKS:
121 if (cb != null) {
122 cb.batteryNeedsCpuUpdate();
123 }
124 break;
125 case MSG_REPORT_POWER_CHANGE:
126 if (cb != null) {
127 cb.batteryPowerChanged(msg.arg1 != 0);
128 }
129 break;
130 }
131 }
132 }
133
134 private final MyHandler mHandler;
135
136 private BatteryCallback mCallback;
137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 /**
139 * The statistics we have collected organized by uids.
140 */
141 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
142 new SparseArray<BatteryStatsImpl.Uid>();
143
144 // A set of pools of currently active timers. When a timer is queried, we will divide the
145 // elapsed time by the number of active timers to arrive at that timer's share of the time.
146 // In order to do this, we must refresh each timer whenever the number of active timers
147 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700148 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
149 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
150 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
151 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
152 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700153 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
154 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700155 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
Nick Pelly6ccaa542012-06-15 15:22:47 -0700156 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700158 // Last partial timers we use for distributing CPU usage.
159 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 // These are the objects that will want to do something when the device
162 // is unplugged from power.
163 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700164
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700165 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700166
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700167 long mHistoryBaseTime;
168 boolean mHaveBatteryLevel = false;
169 boolean mRecordingHistory = true;
170 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700171
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700172 static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
173 static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700174 final Parcel mHistoryBuffer = Parcel.obtain();
175 final HistoryItem mHistoryLastWritten = new HistoryItem();
176 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700177 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700178 int mHistoryBufferLastPos = -1;
179 boolean mHistoryOverflow = false;
180 long mLastHistoryTime = 0;
181
182 final HistoryItem mHistoryCur = new HistoryItem();
183
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700184 HistoryItem mHistory;
185 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700186 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700187 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700188
189 private HistoryItem mHistoryIterator;
190 private boolean mReadOverflow;
191 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 int mStartCount;
194
195 long mBatteryUptime;
196 long mBatteryLastUptime;
197 long mBatteryRealtime;
198 long mBatteryLastRealtime;
199
200 long mUptime;
201 long mUptimeStart;
202 long mLastUptime;
203 long mRealtime;
204 long mRealtimeStart;
205 long mLastRealtime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700208 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700209
Dianne Hackborn617f8772009-03-31 15:04:46 -0700210 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700211 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700212
Dianne Hackborn617f8772009-03-31 15:04:46 -0700213 Counter mInputEventCounter;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700216 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700217
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700218 boolean mAudioOn;
219 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700220
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700221 boolean mVideoOn;
222 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700223
Dianne Hackborn627bba72009-03-24 22:32:56 -0700224 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800225 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700226 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800227 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700228
229 StopwatchTimer mPhoneSignalScanningTimer;
230
Dianne Hackborn627bba72009-03-24 22:32:56 -0700231 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700232 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700233 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700234
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700235 final LongSamplingCounter[] mNetworkActivityCounters =
236 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
237
The Android Open Source Project10592532009-03-18 17:39:46 -0700238 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700239 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700240 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700241
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700242 boolean mGlobalWifiRunning;
243 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700244
The Android Open Source Project10592532009-03-18 17:39:46 -0700245 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700246 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700247
248 /** Bluetooth headset object */
249 BluetoothHeadset mBtHeadset;
250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 /**
252 * These provide time bases that discount the time the device is plugged
253 * in to power.
254 */
255 boolean mOnBattery;
256 boolean mOnBatteryInternal;
257 long mTrackBatteryPastUptime;
258 long mTrackBatteryUptimeStart;
259 long mTrackBatteryPastRealtime;
260 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 long mUnpluggedBatteryUptime;
263 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700264
The Android Open Source Project10592532009-03-18 17:39:46 -0700265 /*
266 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
267 */
Evan Millar633a1742009-04-02 16:36:33 -0700268 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700269 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700270 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700271 int mLowDischargeAmountSinceCharge;
272 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800273 int mDischargeScreenOnUnplugLevel;
274 int mDischargeScreenOffUnplugLevel;
275 int mDischargeAmountScreenOn;
276 int mDischargeAmountScreenOnSinceCharge;
277 int mDischargeAmountScreenOff;
278 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700281
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700282 private long mRadioDataUptime;
283 private long mRadioDataStart;
284
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700285 private int mBluetoothPingCount;
286 private int mBluetoothPingStart = -1;
287
Amith Yamasanif37447b2009-10-08 18:28:01 -0700288 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800289 private int mPhoneServiceStateRaw = -1;
290 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700291
Evan Millarc64edde2009-04-18 12:26:32 -0700292 /*
293 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
294 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700295 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700296 new HashMap<String, SamplingTimer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700297
Evan Millarc64edde2009-04-18 12:26:32 -0700298 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
299 return mKernelWakelockStats;
300 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700301
Evan Millarc64edde2009-04-18 12:26:32 -0700302 private static int sKernelWakelockUpdateVersion = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700303
Evan Millarc64edde2009-04-18 12:26:32 -0700304 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
Dianne Hackborn13ac0412013-06-25 19:34:49 -0700305 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name
306 Process.PROC_QUOTES,
Evan Millarc64edde2009-04-18 12:26:32 -0700307 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
308 Process.PROC_TAB_TERM,
309 Process.PROC_TAB_TERM,
310 Process.PROC_TAB_TERM,
311 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
312 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700313
Todd Poynor73f534a2012-06-19 11:07:26 -0700314 private static final int[] WAKEUP_SOURCES_FORMAT = new int[] {
315 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
316 Process.PROC_TAB_TERM|Process.PROC_COMBINE|
317 Process.PROC_OUT_LONG, // 1: count
318 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
319 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
320 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
321 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
322 Process.PROC_TAB_TERM|Process.PROC_COMBINE
323 |Process.PROC_OUT_LONG, // 6: totalTime
324 };
325
Evan Millarc64edde2009-04-18 12:26:32 -0700326 private final String[] mProcWakelocksName = new String[3];
327 private final long[] mProcWakelocksData = new long[3];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700328
Evan Millarc64edde2009-04-18 12:26:32 -0700329 /*
330 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
331 * to mKernelWakelockStats.
332 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700333 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700334 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700336 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700337
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700338 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700339 private NetworkStats mLastSnapshot;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700340
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700341 @GuardedBy("this")
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700342 private HashSet<String> mMobileIfaces = Sets.newHashSet();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700343 @GuardedBy("this")
344 private HashSet<String> mWifiIfaces = Sets.newHashSet();
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 // For debugging
347 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700348 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700349 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 }
351
352 public static interface Unpluggable {
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800353 void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime);
354 void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700358 * State for keeping track of counting information.
359 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700360 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700361 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700362 final ArrayList<Unpluggable> mUnpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700363 int mLoadedCount;
364 int mLastCount;
365 int mUnpluggedCount;
366 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700367
Dianne Hackborn617f8772009-03-31 15:04:46 -0700368 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700369 mUnpluggables = unpluggables;
Christopher Tate4cee7252010-03-19 14:50:40 -0700370 mPluggedCount = in.readInt();
371 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700372 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700373 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700374 mUnpluggedCount = in.readInt();
375 unpluggables.add(this);
376 }
377
378 Counter(ArrayList<Unpluggable> unpluggables) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700379 mUnpluggables = unpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700380 unpluggables.add(this);
381 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700382
Dianne Hackborn617f8772009-03-31 15:04:46 -0700383 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700384 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700385 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700386 out.writeInt(mUnpluggedCount);
387 }
388
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800389 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700390 mUnpluggedCount = mPluggedCount;
391 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700392 }
393
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800394 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700395 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700396 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700397
Dianne Hackborn617f8772009-03-31 15:04:46 -0700398 /**
399 * Writes a possibly null Counter to a Parcel.
400 *
401 * @param out the Parcel to be written to.
402 * @param counter a Counter, or null.
403 */
404 public static void writeCounterToParcel(Parcel out, Counter counter) {
405 if (counter == null) {
406 out.writeInt(0); // indicates null
407 return;
408 }
409 out.writeInt(1); // indicates non-null
410
411 counter.writeToParcel(out);
412 }
413
414 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700415 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700416 int val;
417 if (which == STATS_LAST) {
418 val = mLastCount;
419 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700420 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700421 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700422 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700423 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700424 val -= mLoadedCount;
425 }
426 }
427
428 return val;
429 }
430
431 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700432 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700433 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
434 + " mUnpluggedCount=" + mUnpluggedCount
435 + " mPluggedCount=" + mPluggedCount);
436 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700437
Christopher Tate4cee7252010-03-19 14:50:40 -0700438 void stepAtomic() {
439 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700440 }
441
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700442 /**
443 * Clear state of this counter.
444 */
445 void reset(boolean detachIfReset) {
446 mCount.set(0);
447 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
448 if (detachIfReset) {
449 detach();
450 }
451 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700452
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700453 void detach() {
454 mUnpluggables.remove(this);
455 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700456
Dianne Hackborn617f8772009-03-31 15:04:46 -0700457 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700458 int count = mCount.get();
459 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700460 }
461
462 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700463 mLoadedCount = in.readInt();
464 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700465 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700466 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700467 }
468 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700469
470 public static class SamplingCounter extends Counter {
Amith Yamasanie43530a2009-08-21 13:11:37 -0700471 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
472 super(unpluggables, in);
473 }
474
475 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
476 super(unpluggables);
477 }
478
Christopher Tate4cee7252010-03-19 14:50:40 -0700479 public void addCountAtomic(long count) {
480 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700481 }
482 }
483
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700484 public static class LongSamplingCounter implements Unpluggable {
485 final ArrayList<Unpluggable> mUnpluggables;
486 long mCount;
487 long mLoadedCount;
488 long mLastCount;
489 long mUnpluggedCount;
490 long mPluggedCount;
491
492 LongSamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
493 mUnpluggables = unpluggables;
494 mPluggedCount = in.readLong();
495 mCount = mPluggedCount;
496 mLoadedCount = in.readLong();
497 mLastCount = 0;
498 mUnpluggedCount = in.readLong();
499 unpluggables.add(this);
500 }
501
502 LongSamplingCounter(ArrayList<Unpluggable> unpluggables) {
503 mUnpluggables = unpluggables;
504 unpluggables.add(this);
505 }
506
507 public void writeToParcel(Parcel out) {
508 out.writeLong(mCount);
509 out.writeLong(mLoadedCount);
510 out.writeLong(mUnpluggedCount);
511 }
512
513 @Override
514 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
515 mUnpluggedCount = mPluggedCount;
516 mCount = mPluggedCount;
517 }
518
519 @Override
520 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
521 mPluggedCount = mCount;
522 }
523
524 public long getCountLocked(int which) {
525 long val;
526 if (which == STATS_LAST) {
527 val = mLastCount;
528 } else {
529 val = mCount;
530 if (which == STATS_SINCE_UNPLUGGED) {
531 val -= mUnpluggedCount;
532 } else if (which != STATS_SINCE_CHARGED) {
533 val -= mLoadedCount;
534 }
535 }
536
537 return val;
538 }
539
540 void addCountLocked(long count) {
541 mCount += count;
542 }
543
544 /**
545 * Clear state of this counter.
546 */
547 void reset(boolean detachIfReset) {
548 mCount = 0;
549 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
550 if (detachIfReset) {
551 detach();
552 }
553 }
554
555 void detach() {
556 mUnpluggables.remove(this);
557 }
558
559 void writeSummaryFromParcelLocked(Parcel out) {
560 out.writeLong(mCount);
561 }
562
563 void readSummaryFromParcelLocked(Parcel in) {
564 mLoadedCount = in.readLong();
565 mCount = mLoadedCount;
566 mLastCount = 0;
567 mUnpluggedCount = mPluggedCount = mLoadedCount;
568 }
569 }
570
Dianne Hackborn617f8772009-03-31 15:04:46 -0700571 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 * State for keeping track of timing information.
573 */
Evan Millarc64edde2009-04-18 12:26:32 -0700574 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 final int mType;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700576 final ArrayList<Unpluggable> mUnpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 int mCount;
579 int mLoadedCount;
580 int mLastCount;
581 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 // Times are in microseconds for better accuracy when dividing by the
584 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 /**
587 * The total time we have accumulated since the start of the original
588 * boot, to the last time something interesting happened in the
589 * current run.
590 */
591 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 /**
594 * The total time we loaded for the previous runs. Subtract this from
595 * mTotalTime to find the time for the current run of the system.
596 */
597 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 /**
600 * The run time of the last run of the system, as loaded from the
601 * saved data.
602 */
603 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 /**
606 * The value of mTotalTime when unplug() was last called. Subtract
607 * this from mTotalTime to find the time since the last unplug from
608 * power.
609 */
610 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700611
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700612 /**
613 * Constructs from a parcel.
614 * @param type
615 * @param unpluggables
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700616 * @param in
617 */
Evan Millarc64edde2009-04-18 12:26:32 -0700618 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700620 mUnpluggables = unpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 mCount = in.readInt();
623 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700624 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 mUnpluggedCount = in.readInt();
626 mTotalTime = in.readLong();
627 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700628 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 mUnpluggedTime = in.readLong();
630 unpluggables.add(this);
631 }
632
Evan Millarc64edde2009-04-18 12:26:32 -0700633 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700635 mUnpluggables = unpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 unpluggables.add(this);
637 }
Evan Millarc64edde2009-04-18 12:26:32 -0700638
639 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700640
Evan Millarc64edde2009-04-18 12:26:32 -0700641 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700642
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700643 /**
644 * Clear state of this timer. Returns true if the timer is inactive
645 * so can be completely dropped.
646 */
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700647 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700648 mTotalTime = mLoadedTime = mLastTime = 0;
649 mCount = mLoadedCount = mLastCount = 0;
650 if (detachIfReset) {
651 detach();
652 }
653 return true;
654 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700655
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700656 void detach() {
657 mUnpluggables.remove(this);
658 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800660 public void writeToParcel(Parcel out, long batteryRealtime) {
661 out.writeInt(mCount);
662 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 out.writeInt(mUnpluggedCount);
664 out.writeLong(computeRunTimeLocked(batteryRealtime));
665 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800666 out.writeLong(mUnpluggedTime);
667 }
668
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800669 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 if (DEBUG && mType < 0) {
671 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
672 + " old mUnpluggedTime=" + mUnpluggedTime
673 + " old mUnpluggedCount=" + mUnpluggedCount);
674 }
675 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
676 mUnpluggedCount = mCount;
677 if (DEBUG && mType < 0) {
678 Log.v(TAG, "unplug #" + mType
679 + ": new mUnpluggedTime=" + mUnpluggedTime
680 + " new mUnpluggedCount=" + mUnpluggedCount);
681 }
682 }
683
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800684 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700685 if (DEBUG && mType < 0) {
686 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
687 + " old mTotalTime=" + mTotalTime);
688 }
689 mTotalTime = computeRunTimeLocked(batteryRealtime);
690 mCount = computeCurrentCountLocked();
691 if (DEBUG && mType < 0) {
692 Log.v(TAG, "plug #" + mType
693 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 }
695 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800697 /**
698 * Writes a possibly null Timer to a Parcel.
699 *
700 * @param out the Parcel to be written to.
701 * @param timer a Timer, or null.
702 */
703 public static void writeTimerToParcel(Parcel out, Timer timer,
704 long batteryRealtime) {
705 if (timer == null) {
706 out.writeInt(0); // indicates null
707 return;
708 }
709 out.writeInt(1); // indicates non-null
710
711 timer.writeToParcel(out, batteryRealtime);
712 }
713
714 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700715 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800716 long val;
717 if (which == STATS_LAST) {
718 val = mLastTime;
719 } else {
720 val = computeRunTimeLocked(batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700721 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 val -= mUnpluggedTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700723 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800724 val -= mLoadedTime;
725 }
726 }
727
728 return val;
729 }
730
731 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700732 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800733 int val;
734 if (which == STATS_LAST) {
735 val = mLastCount;
736 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700737 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700738 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700740 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 val -= mLoadedCount;
742 }
743 }
744
745 return val;
746 }
747
Dianne Hackborn627bba72009-03-24 22:32:56 -0700748 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -0700749 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
751 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700752 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700754 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700756 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700757
758
Evan Millarc64edde2009-04-18 12:26:32 -0700759 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
760 long runTime = computeRunTimeLocked(batteryRealtime);
761 // Divide by 1000 for backwards compatibility
762 out.writeLong((runTime + 500) / 1000);
Evan Millarc64edde2009-04-18 12:26:32 -0700763 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -0700764 }
765
766 void readSummaryFromParcelLocked(Parcel in) {
767 // Multiply by 1000 for backwards compatibility
768 mTotalTime = mLoadedTime = in.readLong() * 1000;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700769 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700770 mUnpluggedTime = mTotalTime;
771 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700772 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700773 mUnpluggedCount = mCount;
774 }
775 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700776
Evan Millarc64edde2009-04-18 12:26:32 -0700777 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700778
Evan Millarc64edde2009-04-18 12:26:32 -0700779 /**
780 * The most recent reported count from /proc/wakelocks.
781 */
782 int mCurrentReportedCount;
783
784 /**
785 * The reported count from /proc/wakelocks when unplug() was last
786 * called.
787 */
788 int mUnpluggedReportedCount;
789
790 /**
791 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700792 */
Evan Millarc64edde2009-04-18 12:26:32 -0700793 long mCurrentReportedTotalTime;
794
795
796 /**
797 * The reported total_time from /proc/wakelocks when unplug() was last
798 * called.
799 */
800 long mUnpluggedReportedTotalTime;
801
802 /**
803 * Whether we are currently in a discharge cycle.
804 */
805 boolean mInDischarge;
806
807 /**
808 * Whether we are currently recording reported values.
809 */
810 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700811
Evan Millarc64edde2009-04-18 12:26:32 -0700812 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800813 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -0700814 */
815 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700816
Evan Millarc64edde2009-04-18 12:26:32 -0700817 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
818 super(0, unpluggables, in);
819 mCurrentReportedCount = in.readInt();
820 mUnpluggedReportedCount = in.readInt();
821 mCurrentReportedTotalTime = in.readLong();
822 mUnpluggedReportedTotalTime = in.readLong();
823 mTrackingReportedValues = in.readInt() == 1;
824 mInDischarge = inDischarge;
825 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700826
827 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
Evan Millarc64edde2009-04-18 12:26:32 -0700828 boolean trackReportedValues) {
829 super(0, unpluggables);
830 mTrackingReportedValues = trackReportedValues;
831 mInDischarge = inDischarge;
832 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700833
Evan Millarc64edde2009-04-18 12:26:32 -0700834 public void setStale() {
835 mTrackingReportedValues = false;
836 mUnpluggedReportedTotalTime = 0;
837 mUnpluggedReportedCount = 0;
838 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700839
Evan Millarc64edde2009-04-18 12:26:32 -0700840 public void setUpdateVersion(int version) {
841 mUpdateVersion = version;
842 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700843
Evan Millarc64edde2009-04-18 12:26:32 -0700844 public int getUpdateVersion() {
845 return mUpdateVersion;
846 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700847
Evan Millarc64edde2009-04-18 12:26:32 -0700848 public void updateCurrentReportedCount(int count) {
849 if (mInDischarge && mUnpluggedReportedCount == 0) {
850 // Updating the reported value for the first time.
851 mUnpluggedReportedCount = count;
852 // If we are receiving an update update mTrackingReportedValues;
853 mTrackingReportedValues = true;
854 }
855 mCurrentReportedCount = count;
856 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700857
Evan Millarc64edde2009-04-18 12:26:32 -0700858 public void updateCurrentReportedTotalTime(long totalTime) {
859 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
860 // Updating the reported value for the first time.
861 mUnpluggedReportedTotalTime = totalTime;
862 // If we are receiving an update update mTrackingReportedValues;
863 mTrackingReportedValues = true;
864 }
865 mCurrentReportedTotalTime = totalTime;
866 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700867
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800868 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
869 super.unplug(elapsedRealtime, batteryUptime, batteryRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -0700870 if (mTrackingReportedValues) {
871 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
872 mUnpluggedReportedCount = mCurrentReportedCount;
873 }
874 mInDischarge = true;
875 }
876
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800877 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
878 super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -0700879 mInDischarge = false;
880 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700881
Evan Millarc64edde2009-04-18 12:26:32 -0700882 public void logState(Printer pw, String prefix) {
883 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700884 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -0700885 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
886 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
887 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
888 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700889
Evan Millarc64edde2009-04-18 12:26:32 -0700890 protected long computeRunTimeLocked(long curBatteryRealtime) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700891 return mTotalTime + (mInDischarge && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -0700892 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
893 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700894
Evan Millarc64edde2009-04-18 12:26:32 -0700895 protected int computeCurrentCountLocked() {
896 return mCount + (mInDischarge && mTrackingReportedValues
897 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
898 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700899
Evan Millarc64edde2009-04-18 12:26:32 -0700900 public void writeToParcel(Parcel out, long batteryRealtime) {
901 super.writeToParcel(out, batteryRealtime);
902 out.writeInt(mCurrentReportedCount);
903 out.writeInt(mUnpluggedReportedCount);
904 out.writeLong(mCurrentReportedTotalTime);
905 out.writeLong(mUnpluggedReportedTotalTime);
906 out.writeInt(mTrackingReportedValues ? 1 : 0);
907 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700908
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700909 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
910 super.reset(stats, detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700911 setStale();
912 return true;
913 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700914
Evan Millarc64edde2009-04-18 12:26:32 -0700915 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
916 super.writeSummaryFromParcelLocked(out, batteryRealtime);
917 out.writeLong(mCurrentReportedTotalTime);
918 out.writeInt(mCurrentReportedCount);
919 out.writeInt(mTrackingReportedValues ? 1 : 0);
920 }
921
922 void readSummaryFromParcelLocked(Parcel in) {
923 super.readSummaryFromParcelLocked(in);
924 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
925 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
926 mTrackingReportedValues = in.readInt() == 1;
927 }
928 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700929
Evan Millarc64edde2009-04-18 12:26:32 -0700930 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800931 * A timer that increments in batches. It does not run for durations, but just jumps
932 * for a pre-determined amount.
933 */
934 public static final class BatchTimer extends Timer {
935 final Uid mUid;
936
937 /**
938 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
939 */
940 long mLastAddedTime;
941
942 /**
943 * The last duration that we added to the timer. This is in microseconds.
944 */
945 long mLastAddedDuration;
946
947 /**
948 * Whether we are currently in a discharge cycle.
949 */
950 boolean mInDischarge;
951
952 BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables,
953 boolean inDischarge, Parcel in) {
954 super(type, unpluggables, in);
955 mUid = uid;
956 mLastAddedTime = in.readLong();
957 mLastAddedDuration = in.readLong();
958 mInDischarge = inDischarge;
959 }
960
961 BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables,
962 boolean inDischarge) {
963 super(type, unpluggables);
964 mUid = uid;
965 mInDischarge = inDischarge;
966 }
967
968 @Override
969 public void writeToParcel(Parcel out, long batteryRealtime) {
970 super.writeToParcel(out, batteryRealtime);
971 out.writeLong(mLastAddedTime);
972 out.writeLong(mLastAddedDuration);
973 }
974
975 @Override
976 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
977 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
978 mInDischarge = false;
979 super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
980 }
981
982 @Override
983 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
984 recomputeLastDuration(elapsedRealtime, false);
985 mInDischarge = true;
986 // If we are still within the last added duration, then re-added whatever remains.
987 if (mLastAddedTime == elapsedRealtime) {
988 mTotalTime += mLastAddedDuration;
989 }
990 super.unplug(elapsedRealtime, batteryUptime, batteryRealtime);
991 }
992
993 @Override
994 public void logState(Printer pw, String prefix) {
995 super.logState(pw, prefix);
996 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
997 + " mLastAddedDuration=" + mLastAddedDuration);
998 }
999
1000 private long computeOverage(long curTime) {
1001 if (mLastAddedTime > 0) {
1002 return mLastTime + mLastAddedDuration - curTime;
1003 }
1004 return 0;
1005 }
1006
1007 private void recomputeLastDuration(long curTime, boolean abort) {
1008 final long overage = computeOverage(curTime);
1009 if (overage > 0) {
1010 // Aborting before the duration ran out -- roll back the remaining
1011 // duration. Only do this if currently discharging; otherwise we didn't
1012 // actually add the time.
1013 if (mInDischarge) {
1014 mTotalTime -= overage;
1015 }
1016 if (abort) {
1017 mLastAddedTime = 0;
1018 } else {
1019 mLastAddedTime = curTime;
1020 mLastAddedDuration -= overage;
1021 }
1022 }
1023 }
1024
1025 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
1026 final long now = SystemClock.elapsedRealtime() * 1000;
1027 recomputeLastDuration(now, true);
1028 mLastAddedTime = now;
1029 mLastAddedDuration = durationMillis * 1000;
1030 if (mInDischarge) {
1031 mTotalTime += mLastAddedDuration;
1032 mCount++;
1033 }
1034 }
1035
1036 public void abortLastDuration(BatteryStatsImpl stats) {
1037 final long now = SystemClock.elapsedRealtime() * 1000;
1038 recomputeLastDuration(now, true);
1039 }
1040
1041 @Override
1042 protected int computeCurrentCountLocked() {
1043 return mCount;
1044 }
1045
1046 @Override
1047 protected long computeRunTimeLocked(long curBatteryRealtime) {
1048 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000);
1049 if (overage > 0) {
1050 return mTotalTime = overage;
1051 }
1052 return mTotalTime;
1053 }
1054
1055 @Override
1056 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
1057 final long now = SystemClock.elapsedRealtime() * 1000;
1058 recomputeLastDuration(now, true);
1059 boolean stillActive = mLastAddedTime == now;
1060 super.reset(stats, !stillActive && detachIfReset);
1061 return !stillActive;
1062 }
1063 }
1064
1065 /**
Evan Millarc64edde2009-04-18 12:26:32 -07001066 * State for keeping track of timing information.
1067 */
1068 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001069 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07001070 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001071
Evan Millarc64edde2009-04-18 12:26:32 -07001072 int mNesting;
1073
Evan Millarc64edde2009-04-18 12:26:32 -07001074 /**
1075 * The last time at which we updated the timer. If mNesting is > 0,
1076 * subtract this from the current battery time to find the amount of
1077 * time we have been running since we last computed an update.
1078 */
1079 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001080
Evan Millarc64edde2009-04-18 12:26:32 -07001081 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001082 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -07001083 * was actually held for an interesting duration.
1084 */
1085 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001086
Amith Yamasanif37447b2009-10-08 18:28:01 -07001087 long mTimeout;
1088
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001089 /**
1090 * For partial wake locks, keep track of whether we are in the list
1091 * to consume CPU cycles.
1092 */
1093 boolean mInList;
1094
1095 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -07001096 ArrayList<Unpluggable> unpluggables, Parcel in) {
1097 super(type, unpluggables, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001098 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001099 mTimerPool = timerPool;
1100 mUpdateTime = in.readLong();
1101 }
1102
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001103 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -07001104 ArrayList<Unpluggable> unpluggables) {
1105 super(type, unpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001106 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001107 mTimerPool = timerPool;
1108 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001109
Amith Yamasanif37447b2009-10-08 18:28:01 -07001110 void setTimeout(long timeout) {
1111 mTimeout = timeout;
1112 }
1113
Evan Millarc64edde2009-04-18 12:26:32 -07001114 public void writeToParcel(Parcel out, long batteryRealtime) {
1115 super.writeToParcel(out, batteryRealtime);
1116 out.writeLong(mUpdateTime);
1117 }
1118
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001119 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001120 if (mNesting > 0) {
1121 if (DEBUG && mType < 0) {
1122 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
1123 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001124 super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001125 mUpdateTime = batteryRealtime;
1126 if (DEBUG && mType < 0) {
1127 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
1128 }
1129 }
1130 }
1131
1132 public void logState(Printer pw, String prefix) {
1133 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001134 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001135 + " mAcquireTime=" + mAcquireTime);
1136 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001138 void startRunningLocked(BatteryStatsImpl stats) {
1139 if (mNesting++ == 0) {
1140 mUpdateTime = stats.getBatteryRealtimeLocked(
1141 SystemClock.elapsedRealtime() * 1000);
1142 if (mTimerPool != null) {
1143 // Accumulate time to all currently active timers before adding
1144 // this new one to the pool.
1145 refreshTimersLocked(stats, mTimerPool);
1146 // Add this timer to the active pool
1147 mTimerPool.add(this);
1148 }
1149 // Increment the count
1150 mCount++;
1151 mAcquireTime = mTotalTime;
1152 if (DEBUG && mType < 0) {
1153 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
1154 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1155 + " mAcquireTime=" + mAcquireTime);
1156 }
1157 }
1158 }
1159
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001160 boolean isRunningLocked() {
1161 return mNesting > 0;
1162 }
1163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001164 void stopRunningLocked(BatteryStatsImpl stats) {
1165 // Ignore attempt to stop a timer that isn't running
1166 if (mNesting == 0) {
1167 return;
1168 }
1169 if (--mNesting == 0) {
1170 if (mTimerPool != null) {
1171 // Accumulate time to all active counters, scaled by the total
1172 // active in the pool, before taking this one out of the pool.
1173 refreshTimersLocked(stats, mTimerPool);
1174 // Remove this timer from the active pool
1175 mTimerPool.remove(this);
1176 } else {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001177 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001178 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
1179 mNesting = 1;
1180 mTotalTime = computeRunTimeLocked(batteryRealtime);
1181 mNesting = 0;
1182 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 if (DEBUG && mType < 0) {
1185 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
1186 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1187 + " mAcquireTime=" + mAcquireTime);
1188 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 if (mTotalTime == mAcquireTime) {
1191 // If there was no change in the time, then discard this
1192 // count. A somewhat cheezy strategy, but hey.
1193 mCount--;
1194 }
1195 }
1196 }
1197
1198 // Update the total time for all other running Timers with the same type as this Timer
1199 // due to a change in timer count
1200 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -07001201 final ArrayList<StopwatchTimer> pool) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001202 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
1204 final int N = pool.size();
1205 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07001206 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001207 long heldTime = batteryRealtime - t.mUpdateTime;
1208 if (heldTime > 0) {
1209 t.mTotalTime += heldTime / N;
1210 }
1211 t.mUpdateTime = batteryRealtime;
1212 }
1213 }
1214
Evan Millarc64edde2009-04-18 12:26:32 -07001215 @Override
1216 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001217 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
1218 curBatteryRealtime = mUpdateTime + mTimeout;
1219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220 return mTotalTime + (mNesting > 0
1221 ? (curBatteryRealtime - mUpdateTime)
1222 / (mTimerPool != null ? mTimerPool.size() : 1)
1223 : 0);
1224 }
1225
Evan Millarc64edde2009-04-18 12:26:32 -07001226 @Override
1227 protected int computeCurrentCountLocked() {
1228 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 }
1230
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001231 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001232 boolean canDetach = mNesting <= 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001233 super.reset(stats, canDetach && detachIfReset);
1234 if (mNesting > 0) {
1235 mUpdateTime = stats.getBatteryRealtimeLocked(
1236 SystemClock.elapsedRealtime() * 1000);
1237 }
1238 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001239 return canDetach;
1240 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001241
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001242 void detach() {
1243 super.detach();
1244 if (mTimerPool != null) {
1245 mTimerPool.remove(this);
1246 }
1247 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001250 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 mNesting = 0;
1252 }
1253 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001254
Evan Millarc64edde2009-04-18 12:26:32 -07001255 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001256
Todd Poynor73f534a2012-06-19 11:07:26 -07001257 FileInputStream is;
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001258 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -07001259 int len;
Todd Poynor73f534a2012-06-19 11:07:26 -07001260 boolean wakeup_sources = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001261
Evan Millarc64edde2009-04-18 12:26:32 -07001262 try {
Todd Poynor73f534a2012-06-19 11:07:26 -07001263 try {
1264 is = new FileInputStream("/proc/wakelocks");
1265 } catch (java.io.FileNotFoundException e) {
1266 try {
1267 is = new FileInputStream("/d/wakeup_sources");
1268 wakeup_sources = true;
1269 } catch (java.io.FileNotFoundException e2) {
1270 return null;
Evan Millarc64edde2009-04-18 12:26:32 -07001271 }
1272 }
Todd Poynor73f534a2012-06-19 11:07:26 -07001273
1274 len = is.read(buffer);
1275 is.close();
Evan Millarc64edde2009-04-18 12:26:32 -07001276 } catch (java.io.IOException e) {
1277 return null;
1278 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001279
Todd Poynor73f534a2012-06-19 11:07:26 -07001280 if (len > 0) {
1281 int i;
1282 for (i=0; i<len; i++) {
1283 if (buffer[i] == '\0') {
1284 len = i;
1285 break;
1286 }
1287 }
1288 }
1289
1290 return parseProcWakelocks(buffer, len, wakeup_sources);
Evan Millarc64edde2009-04-18 12:26:32 -07001291 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001292
Evan Millarc64edde2009-04-18 12:26:32 -07001293 private final Map<String, KernelWakelockStats> parseProcWakelocks(
Todd Poynor73f534a2012-06-19 11:07:26 -07001294 byte[] wlBuffer, int len, boolean wakeup_sources) {
Evan Millarc64edde2009-04-18 12:26:32 -07001295 String name;
1296 int count;
1297 long totalTime;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001298 int startIndex;
1299 int endIndex;
Evan Millarc64edde2009-04-18 12:26:32 -07001300 int numUpdatedWlNames = 0;
1301
1302 // Advance past the first line.
1303 int i;
1304 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1305 startIndex = endIndex = i + 1;
1306
1307 synchronized(this) {
1308 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001309
Evan Millarc64edde2009-04-18 12:26:32 -07001310 sKernelWakelockUpdateVersion++;
1311 while (endIndex < len) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001312 for (endIndex=startIndex;
1313 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
Evan Millarc64edde2009-04-18 12:26:32 -07001314 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001315 endIndex++; // endIndex is an exclusive upper bound.
1316 // Don't go over the end of the buffer, Process.parseProcLine might
1317 // write to wlBuffer[endIndex]
1318 if (endIndex >= (len - 1) ) {
1319 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -07001320 }
Evan Millarc64edde2009-04-18 12:26:32 -07001321
1322 String[] nameStringArray = mProcWakelocksName;
1323 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001324 // Stomp out any bad characters since this is from a circular buffer
1325 // A corruption is seen sometimes that results in the vm crashing
1326 // This should prevent crashes and the line will probably fail to parse
1327 for (int j = startIndex; j < endIndex; j++) {
1328 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1329 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001330 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
Todd Poynor73f534a2012-06-19 11:07:26 -07001331 wakeup_sources ? WAKEUP_SOURCES_FORMAT :
1332 PROC_WAKELOCKS_FORMAT,
1333 nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001334
Evan Millarc64edde2009-04-18 12:26:32 -07001335 name = nameStringArray[0];
1336 count = (int) wlData[1];
Todd Poynor73f534a2012-06-19 11:07:26 -07001337
1338 if (wakeup_sources) {
1339 // convert milliseconds to microseconds
1340 totalTime = wlData[2] * 1000;
1341 } else {
1342 // convert nanoseconds to microseconds with rounding.
1343 totalTime = (wlData[2] + 500) / 1000;
1344 }
Evan Millarc64edde2009-04-18 12:26:32 -07001345
Amith Yamasani53b707b2009-09-30 11:05:30 -07001346 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001347 if (!m.containsKey(name)) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001348 m.put(name, new KernelWakelockStats(count, totalTime,
Evan Millarc64edde2009-04-18 12:26:32 -07001349 sKernelWakelockUpdateVersion));
1350 numUpdatedWlNames++;
1351 } else {
1352 KernelWakelockStats kwlStats = m.get(name);
1353 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1354 kwlStats.mCount += count;
1355 kwlStats.mTotalTime += totalTime;
1356 } else {
1357 kwlStats.mCount = count;
1358 kwlStats.mTotalTime = totalTime;
1359 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1360 numUpdatedWlNames++;
1361 }
1362 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001363 }
Evan Millarc64edde2009-04-18 12:26:32 -07001364 startIndex = endIndex;
1365 }
1366
1367 if (m.size() != numUpdatedWlNames) {
1368 // Don't report old data.
1369 Iterator<KernelWakelockStats> itr = m.values().iterator();
1370 while (itr.hasNext()) {
1371 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1372 itr.remove();
1373 }
1374 }
1375 }
1376 return m;
1377 }
1378 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001379
Evan Millarc64edde2009-04-18 12:26:32 -07001380 private class KernelWakelockStats {
1381 public int mCount;
1382 public long mTotalTime;
1383 public int mVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001384
Evan Millarc64edde2009-04-18 12:26:32 -07001385 KernelWakelockStats(int count, long totalTime, int version) {
1386 mCount = count;
1387 mTotalTime = totalTime;
1388 mVersion = version;
1389 }
1390 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001391
Evan Millarc64edde2009-04-18 12:26:32 -07001392 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001393 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001394 * doesn't already exist.
1395 */
1396 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1397 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1398 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001399 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07001400 true /* track reported values */);
1401 mKernelWakelockStats.put(name, kwlt);
1402 }
1403 return kwlt;
1404 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001405
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001406 /**
1407 * Radio uptime in microseconds when transferring data. This value is very approximate.
1408 * @return
1409 */
1410 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001411 try {
1412 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
1413 if (!awakeTimeFile.exists()) return 0;
1414 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
1415 String line = br.readLine();
1416 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001417 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001418 } catch (NumberFormatException nfe) {
1419 // Nothing
1420 } catch (IOException ioe) {
1421 // Nothing
1422 }
1423 return 0;
1424 }
1425
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001426 /**
1427 * @deprecated use getRadioDataUptime
1428 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001429 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001430 return getRadioDataUptime() / 1000;
1431 }
1432
1433 /**
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001434 * Returns the duration that the cell radio was up for data transfers.
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001435 */
1436 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001437 if (mRadioDataStart == -1) {
1438 return mRadioDataUptime;
1439 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001440 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001441 }
1442 }
1443
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001444 private int getCurrentBluetoothPingCount() {
1445 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001446 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1447 if (deviceList.size() > 0) {
1448 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001449 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001450 }
1451 return -1;
1452 }
1453
1454 public int getBluetoothPingCount() {
1455 if (mBluetoothPingStart == -1) {
1456 return mBluetoothPingCount;
1457 } else if (mBtHeadset != null) {
1458 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1459 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001460 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001461 }
1462
1463 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001464 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1465 mBluetoothPingStart = getCurrentBluetoothPingCount();
1466 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001467 mBtHeadset = headset;
1468 }
1469
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001470 int mChangedBufferStates = 0;
1471
1472 void addHistoryBufferLocked(long curTime) {
1473 if (!mHaveBatteryLevel || !mRecordingHistory) {
1474 return;
1475 }
1476
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001477 final long timeDiff = (mHistoryBaseTime+curTime) - mHistoryLastWritten.time;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001478 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001479 && timeDiff < 2000
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001480 && ((mHistoryLastWritten.states^mHistoryCur.states)&mChangedBufferStates) == 0) {
1481 // If the current is the same as the one before, then we no
1482 // longer need the entry.
1483 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
1484 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
1485 mHistoryBufferLastPos = -1;
1486 if (mHistoryLastLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001487 && timeDiff < 500 && mHistoryLastLastWritten.same(mHistoryCur)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001488 // If this results in us returning to the state written
1489 // prior to the last one, then we can just delete the last
1490 // written one and drop the new one. Nothing more to do.
1491 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
1492 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1493 return;
1494 }
1495 mChangedBufferStates |= mHistoryLastWritten.states^mHistoryCur.states;
1496 curTime = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001497 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001498 } else {
1499 mChangedBufferStates = 0;
1500 }
1501
1502 final int dataSize = mHistoryBuffer.dataSize();
1503 if (dataSize >= MAX_HISTORY_BUFFER) {
1504 if (!mHistoryOverflow) {
1505 mHistoryOverflow = true;
1506 addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW);
1507 }
1508
1509 // Once we've reached the maximum number of items, we only
1510 // record changes to the battery level and the most interesting states.
1511 // Once we've reached the maximum maximum number of items, we only
1512 // record changes to the battery level.
1513 if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
1514 (dataSize >= MAX_MAX_HISTORY_BUFFER
Amith Yamasani45f06462011-11-21 16:08:34 -08001515 || ((mHistoryLastWritten.states^mHistoryCur.states)
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001516 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
1517 return;
1518 }
1519 }
1520
1521 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE);
1522 }
1523
1524 void addHistoryBufferLocked(long curTime, byte cmd) {
1525 int origPos = 0;
1526 if (mIteratingHistory) {
1527 origPos = mHistoryBuffer.dataPosition();
1528 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
1529 }
1530 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
1531 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
1532 mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
1533 mHistoryLastWritten.writeDelta(mHistoryBuffer, mHistoryLastLastWritten);
1534 mLastHistoryTime = curTime;
1535 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
1536 + " now " + mHistoryBuffer.dataPosition()
1537 + " size is now " + mHistoryBuffer.dataSize());
1538 if (mIteratingHistory) {
1539 mHistoryBuffer.setDataPosition(origPos);
1540 }
1541 }
1542
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001543 int mChangedStates = 0;
1544
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001545 void addHistoryRecordLocked(long curTime) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001546 addHistoryBufferLocked(curTime);
1547
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001548 if (!USE_OLD_HISTORY) {
1549 return;
1550 }
1551
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001552 if (!mHaveBatteryLevel || !mRecordingHistory) {
1553 return;
1554 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001555
1556 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001557 // and no states have since the last recorded entry changed and
1558 // are now resetting back to their original value, then just collapse
1559 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001560 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001561 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000)
1562 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001563 // If the current is the same as the one before, then we no
1564 // longer need the entry.
1565 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001566 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500)
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001567 && mHistoryLastEnd.same(mHistoryCur)) {
1568 mHistoryLastEnd.next = null;
1569 mHistoryEnd.next = mHistoryCache;
1570 mHistoryCache = mHistoryEnd;
1571 mHistoryEnd = mHistoryLastEnd;
1572 mHistoryLastEnd = null;
1573 } else {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001574 mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001575 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
1576 }
1577 return;
1578 }
1579
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001580 mChangedStates = 0;
1581
1582 if (mNumHistoryItems == MAX_HISTORY_ITEMS
1583 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001584 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
1585 }
1586
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001587 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
1588 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001589 // record changes to the battery level and the most interesting states.
1590 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001591 // record changes to the battery level.
1592 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001593 == mHistoryCur.batteryLevel &&
1594 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
1595 || ((mHistoryEnd.states^mHistoryCur.states)
1596 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001597 return;
1598 }
1599 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001600
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001601 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
1602 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001603
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001604 void addHistoryRecordLocked(long curTime, byte cmd) {
1605 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001606 if (rec != null) {
1607 mHistoryCache = rec.next;
1608 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001609 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001610 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001611 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001612
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001613 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001614 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001615
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001616 void addHistoryRecordLocked(HistoryItem rec) {
1617 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001618 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001619 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001620 if (mHistoryEnd != null) {
1621 mHistoryEnd.next = rec;
1622 mHistoryEnd = rec;
1623 } else {
1624 mHistory = mHistoryEnd = rec;
1625 }
1626 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001627
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001628 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001629 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001630 if (USE_OLD_HISTORY) {
1631 if (mHistory != null) {
1632 mHistoryEnd.next = mHistoryCache;
1633 mHistoryCache = mHistory;
1634 mHistory = mHistoryLastEnd = mHistoryEnd = null;
1635 }
1636 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001637 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001638
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001639 mHistoryBaseTime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001640 mLastHistoryTime = 0;
1641
1642 mHistoryBuffer.setDataSize(0);
1643 mHistoryBuffer.setDataPosition(0);
1644 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER/2);
1645 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1646 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
1647 mHistoryBufferLastPos = -1;
1648 mHistoryOverflow = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001649 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001650
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001651 public void doUnplugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001652 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001653 mUnpluggables.get(i).unplug(elapsedRealtime, batteryUptime, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001655
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001656 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001657 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001658 mRadioDataUptime = 0;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001659
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001660 // Track bt headset ping count
1661 mBluetoothPingStart = getCurrentBluetoothPingCount();
1662 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001664
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001665 public void doPlugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001667 mUnpluggables.get(i).plug(elapsedRealtime, batteryUptime, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001668 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001669
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001670 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001671 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001672 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001673
1674 // Track bt headset ping count
1675 mBluetoothPingCount = getBluetoothPingCount();
1676 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001678
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001679 int mWakeLockNesting;
1680
1681 public void noteStartWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001682 if (type == WAKE_TYPE_PARTIAL) {
1683 // Only care about partial wake locks, since full wake locks
1684 // will be canceled when the user puts the screen to sleep.
1685 if (mWakeLockNesting == 0) {
1686 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
1687 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
1688 + Integer.toHexString(mHistoryCur.states));
1689 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1690 }
1691 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001692 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001693 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001694 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1695 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1696 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1697 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001698 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
1699 }
1700 }
1701
1702 public void noteStopWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001703 if (type == WAKE_TYPE_PARTIAL) {
1704 mWakeLockNesting--;
1705 if (mWakeLockNesting == 0) {
1706 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
1707 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
1708 + Integer.toHexString(mHistoryCur.states));
1709 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1710 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001711 }
1712 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001713 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1714 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1715 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1716 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001717 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
1718 }
1719 }
1720
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001721 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1722 int N = ws.size();
1723 for (int i=0; i<N; i++) {
1724 noteStartWakeLocked(ws.get(i), pid, name, type);
1725 }
1726 }
1727
1728 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1729 int N = ws.size();
1730 for (int i=0; i<N; i++) {
1731 noteStopWakeLocked(ws.get(i), pid, name, type);
1732 }
1733 }
1734
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001735 public int startAddingCpuLocked() {
1736 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
1737
1738 if (mScreenOn) {
1739 return 0;
1740 }
1741
1742 final int N = mPartialTimers.size();
1743 if (N == 0) {
1744 mLastPartialTimers.clear();
1745 return 0;
1746 }
1747
1748 // How many timers should consume CPU? Only want to include ones
1749 // that have already been in the list.
1750 for (int i=0; i<N; i++) {
1751 StopwatchTimer st = mPartialTimers.get(i);
1752 if (st.mInList) {
1753 Uid uid = st.mUid;
1754 // We don't include the system UID, because it so often
1755 // holds wake locks at one request or another of an app.
1756 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1757 return 50;
1758 }
1759 }
1760 }
1761
1762 return 0;
1763 }
1764
1765 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
1766 final int N = mPartialTimers.size();
1767 if (perc != 0) {
1768 int num = 0;
1769 for (int i=0; i<N; i++) {
1770 StopwatchTimer st = mPartialTimers.get(i);
1771 if (st.mInList) {
1772 Uid uid = st.mUid;
1773 // We don't include the system UID, because it so often
1774 // holds wake locks at one request or another of an app.
1775 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1776 num++;
1777 }
1778 }
1779 }
1780 if (num != 0) {
1781 for (int i=0; i<N; i++) {
1782 StopwatchTimer st = mPartialTimers.get(i);
1783 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001784 Uid uid = st.mUid;
1785 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07001786 int myUTime = utime/num;
1787 int mySTime = stime/num;
1788 utime -= myUTime;
1789 stime -= mySTime;
1790 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001791 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
1792 proc.addCpuTimeLocked(myUTime, mySTime);
1793 proc.addSpeedStepTimes(cpuSpeedTimes);
1794 }
1795 }
1796 }
1797 }
1798
1799 // Just in case, collect any lost CPU time.
1800 if (utime != 0 || stime != 0) {
1801 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
1802 if (uid != null) {
1803 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
1804 proc.addCpuTimeLocked(utime, stime);
1805 proc.addSpeedStepTimes(cpuSpeedTimes);
1806 }
1807 }
1808 }
1809
1810 final int NL = mLastPartialTimers.size();
1811 boolean diff = N != NL;
1812 for (int i=0; i<NL && !diff; i++) {
1813 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
1814 }
1815 if (!diff) {
1816 for (int i=0; i<NL; i++) {
1817 mPartialTimers.get(i).mInList = true;
1818 }
1819 return;
1820 }
1821
1822 for (int i=0; i<NL; i++) {
1823 mLastPartialTimers.get(i).mInList = false;
1824 }
1825 mLastPartialTimers.clear();
1826 for (int i=0; i<N; i++) {
1827 StopwatchTimer st = mPartialTimers.get(i);
1828 st.mInList = true;
1829 mLastPartialTimers.add(st);
1830 }
1831 }
1832
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001833 public void noteProcessDiedLocked(int uid, int pid) {
1834 Uid u = mUidStats.get(uid);
1835 if (u != null) {
1836 u.mPids.remove(pid);
1837 }
1838 }
1839
1840 public long getProcessWakeTime(int uid, int pid, long realtime) {
1841 Uid u = mUidStats.get(uid);
1842 if (u != null) {
1843 Uid.Pid p = u.mPids.get(pid);
1844 if (p != null) {
1845 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
1846 }
1847 }
1848 return 0;
1849 }
1850
1851 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
1852 Uid u = mUidStats.get(uid);
1853 if (u != null) {
1854 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
1855 }
1856 }
1857
Dianne Hackborn287952c2010-09-22 22:34:31 -07001858 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
1859 Uid u = mUidStats.get(uid);
1860 if (u != null) {
1861 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
1862 }
1863 }
1864
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001865 int mSensorNesting;
1866
1867 public void noteStartSensorLocked(int uid, int sensor) {
1868 if (mSensorNesting == 0) {
1869 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
1870 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
1871 + Integer.toHexString(mHistoryCur.states));
1872 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1873 }
1874 mSensorNesting++;
1875 getUidStatsLocked(uid).noteStartSensor(sensor);
1876 }
1877
1878 public void noteStopSensorLocked(int uid, int sensor) {
1879 mSensorNesting--;
1880 if (mSensorNesting == 0) {
1881 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
1882 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
1883 + Integer.toHexString(mHistoryCur.states));
1884 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1885 }
1886 getUidStatsLocked(uid).noteStopSensor(sensor);
1887 }
1888
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001889 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001890
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001891 public void noteStartGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001892 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001893 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001894 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
1895 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001896 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001897 }
1898 mGpsNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001899 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001900 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001901
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001902 public void noteStopGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001903 mGpsNesting--;
1904 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001905 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001906 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
1907 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001908 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001909 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001910 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001911 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913 public void noteScreenOnLocked() {
1914 if (!mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001915 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001916 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
1917 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001918 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001919 mScreenOn = true;
1920 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001921 if (mScreenBrightnessBin >= 0) {
1922 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1923 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001924
1925 // Fake a wake lock, so we consider the device waked as long
1926 // as the screen is on.
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001927 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001928
1929 // Update discharge amounts.
1930 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001931 updateDischargeScreenLevelsLocked(false, true);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001932 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001933 }
1934 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001936 public void noteScreenOffLocked() {
1937 if (mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001938 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001939 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
1940 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001941 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001942 mScreenOn = false;
1943 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001944 if (mScreenBrightnessBin >= 0) {
1945 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1946 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001947
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001948 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001949
1950 // Update discharge amounts.
1951 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001952 updateDischargeScreenLevelsLocked(true, false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001953 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001954 }
1955 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001956
Dianne Hackborn617f8772009-03-31 15:04:46 -07001957 public void noteScreenBrightnessLocked(int brightness) {
1958 // Bin the brightness.
1959 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1960 if (bin < 0) bin = 0;
1961 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1962 if (mScreenBrightnessBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001963 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
1964 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001965 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
1966 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001967 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001968 if (mScreenOn) {
1969 if (mScreenBrightnessBin >= 0) {
1970 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1971 }
1972 mScreenBrightnessTimer[bin].startRunningLocked(this);
1973 }
1974 mScreenBrightnessBin = bin;
1975 }
1976 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001977
Christopher Tate4cee7252010-03-19 14:50:40 -07001978 public void noteInputEventAtomic() {
1979 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001980 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001981
Dianne Hackborn617f8772009-03-31 15:04:46 -07001982 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001983 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001984 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001986 public void notePhoneOnLocked() {
1987 if (!mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001988 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001989 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
1990 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001991 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001992 mPhoneOn = true;
1993 mPhoneOnTimer.startRunningLocked(this);
1994 }
1995 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001997 public void notePhoneOffLocked() {
1998 if (mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001999 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002000 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
2001 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002002 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 mPhoneOn = false;
2004 mPhoneOnTimer.stopRunningLocked(this);
2005 }
2006 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002007
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002008 void stopAllSignalStrengthTimersLocked(int except) {
Wink Saville52840902011-02-18 12:40:47 -08002009 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002010 if (i == except) {
2011 continue;
2012 }
2013 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
2014 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
2015 }
2016 }
2017 }
2018
Dianne Hackborne4a59512010-12-07 11:08:07 -08002019 private int fixPhoneServiceState(int state, int signalBin) {
2020 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
2021 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2022 // to infer that we are scanning from other data.
2023 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08002024 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002025 state = ServiceState.STATE_IN_SERVICE;
2026 }
2027 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002028
Dianne Hackborne4a59512010-12-07 11:08:07 -08002029 return state;
2030 }
2031
2032 private void updateAllPhoneStateLocked(int state, int simState, int bin) {
2033 boolean scanning = false;
2034 boolean newHistory = false;
2035
2036 mPhoneServiceStateRaw = state;
2037 mPhoneSimStateRaw = simState;
2038 mPhoneSignalStrengthBinRaw = bin;
2039
2040 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
2041 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2042 // to infer that we are scanning from other data.
2043 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08002044 && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002045 state = ServiceState.STATE_IN_SERVICE;
2046 }
2047 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002048
2049 // If the phone is powered off, stop all timers.
2050 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002051 bin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002052
Dianne Hackborne4a59512010-12-07 11:08:07 -08002053 // If we are in service, make sure the correct signal string timer is running.
2054 } else if (state == ServiceState.STATE_IN_SERVICE) {
2055 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002056
2057 // If we're out of service, we are in the lowest signal strength
2058 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07002059 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002060 scanning = true;
Wink Saville52840902011-02-18 12:40:47 -08002061 bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002062 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002063 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08002064 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002065 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
2066 + Integer.toHexString(mHistoryCur.states));
Amith Yamasanif37447b2009-10-08 18:28:01 -07002067 mPhoneSignalScanningTimer.startRunningLocked(this);
2068 }
2069 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002070
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002071 if (!scanning) {
2072 // If we are no longer scanning, then stop the scanning timer.
2073 if (mPhoneSignalScanningTimer.isRunningLocked()) {
2074 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
2075 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
2076 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002077 newHistory = true;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002078 mPhoneSignalScanningTimer.stopRunningLocked(this);
2079 }
2080 }
2081
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002082 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002083 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
2084 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002085 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002086 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002087 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002088 mPhoneServiceState = state;
2089 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08002090
2091 if (mPhoneSignalStrengthBin != bin) {
2092 if (mPhoneSignalStrengthBin >= 0) {
2093 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
2094 }
2095 if (bin >= 0) {
2096 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
2097 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
2098 }
2099 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
2100 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
2101 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
2102 + Integer.toHexString(mHistoryCur.states));
2103 newHistory = true;
2104 } else {
2105 stopAllSignalStrengthTimersLocked(-1);
2106 }
2107 mPhoneSignalStrengthBin = bin;
2108 }
2109
2110 if (newHistory) {
2111 addHistoryRecordLocked(SystemClock.elapsedRealtime());
2112 }
2113 }
2114
2115 /**
2116 * Telephony stack updates the phone state.
2117 * @param state phone state from ServiceState.getState()
2118 */
2119 public void notePhoneStateLocked(int state, int simState) {
2120 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002121 }
2122
Wink Savillee9b06d72009-05-18 21:47:50 -07002123 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07002124 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08002125 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08002126 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002127 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002128
Dianne Hackborn627bba72009-03-24 22:32:56 -07002129 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
2130 int bin = DATA_CONNECTION_NONE;
2131 if (hasData) {
2132 switch (dataType) {
2133 case TelephonyManager.NETWORK_TYPE_EDGE:
2134 bin = DATA_CONNECTION_EDGE;
2135 break;
2136 case TelephonyManager.NETWORK_TYPE_GPRS:
2137 bin = DATA_CONNECTION_GPRS;
2138 break;
2139 case TelephonyManager.NETWORK_TYPE_UMTS:
2140 bin = DATA_CONNECTION_UMTS;
2141 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002142 case TelephonyManager.NETWORK_TYPE_CDMA:
2143 bin = DATA_CONNECTION_CDMA;
2144 break;
2145 case TelephonyManager.NETWORK_TYPE_EVDO_0:
2146 bin = DATA_CONNECTION_EVDO_0;
2147 break;
2148 case TelephonyManager.NETWORK_TYPE_EVDO_A:
2149 bin = DATA_CONNECTION_EVDO_A;
2150 break;
2151 case TelephonyManager.NETWORK_TYPE_1xRTT:
2152 bin = DATA_CONNECTION_1xRTT;
2153 break;
2154 case TelephonyManager.NETWORK_TYPE_HSDPA:
2155 bin = DATA_CONNECTION_HSDPA;
2156 break;
2157 case TelephonyManager.NETWORK_TYPE_HSUPA:
2158 bin = DATA_CONNECTION_HSUPA;
2159 break;
2160 case TelephonyManager.NETWORK_TYPE_HSPA:
2161 bin = DATA_CONNECTION_HSPA;
2162 break;
2163 case TelephonyManager.NETWORK_TYPE_IDEN:
2164 bin = DATA_CONNECTION_IDEN;
2165 break;
2166 case TelephonyManager.NETWORK_TYPE_EVDO_B:
2167 bin = DATA_CONNECTION_EVDO_B;
2168 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07002169 case TelephonyManager.NETWORK_TYPE_LTE:
2170 bin = DATA_CONNECTION_LTE;
2171 break;
2172 case TelephonyManager.NETWORK_TYPE_EHRPD:
2173 bin = DATA_CONNECTION_EHRPD;
2174 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07002175 default:
2176 bin = DATA_CONNECTION_OTHER;
2177 break;
2178 }
2179 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002180 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002181 if (mPhoneDataConnectionType != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002182 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
2183 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002184 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
2185 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002186 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07002187 if (mPhoneDataConnectionType >= 0) {
2188 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
2189 }
2190 mPhoneDataConnectionType = bin;
2191 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
2192 }
2193 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002194
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002195 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002196 if (!mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002197 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002198 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
2199 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002200 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002201 mWifiOn = true;
2202 mWifiOnTimer.startRunningLocked(this);
2203 }
2204 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002205
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002206 public void noteWifiOffLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002207 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002208 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002209 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
2210 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002211 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002212 mWifiOn = false;
2213 mWifiOnTimer.stopRunningLocked(this);
2214 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002215 if (mWifiOnUid >= 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002216 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002217 mWifiOnUid = -1;
2218 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002219 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002220
2221 public void noteAudioOnLocked(int uid) {
2222 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002223 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002224 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
2225 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002226 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002227 mAudioOn = true;
2228 mAudioOnTimer.startRunningLocked(this);
2229 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002230 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002231 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002232
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002233 public void noteAudioOffLocked(int uid) {
2234 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002235 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002236 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
2237 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002238 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002239 mAudioOn = false;
2240 mAudioOnTimer.stopRunningLocked(this);
2241 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002242 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002243 }
2244
2245 public void noteVideoOnLocked(int uid) {
2246 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002247 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002248 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
2249 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002250 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002251 mVideoOn = true;
2252 mVideoOnTimer.startRunningLocked(this);
2253 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002254 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002255 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002256
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002257 public void noteVideoOffLocked(int uid) {
2258 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002259 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002260 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
2261 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002262 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002263 mVideoOn = false;
2264 mVideoOnTimer.stopRunningLocked(this);
2265 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002266 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002267 }
2268
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002269 public void noteActivityResumedLocked(int uid) {
2270 getUidStatsLocked(uid).noteActivityResumedLocked();
2271 }
2272
2273 public void noteActivityPausedLocked(int uid) {
2274 getUidStatsLocked(uid).noteActivityPausedLocked();
2275 }
2276
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002277 public void noteVibratorOnLocked(int uid, long durationMillis) {
2278 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
2279 }
2280
2281 public void noteVibratorOffLocked(int uid) {
2282 getUidStatsLocked(uid).noteVibratorOffLocked();
2283 }
2284
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002285 public void noteWifiRunningLocked(WorkSource ws) {
2286 if (!mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002287 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002288 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
2289 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002290 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002291 mGlobalWifiRunning = true;
2292 mGlobalWifiRunningTimer.startRunningLocked(this);
2293 int N = ws.size();
2294 for (int i=0; i<N; i++) {
2295 getUidStatsLocked(ws.get(i)).noteWifiRunningLocked();
2296 }
2297 } else {
2298 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002299 }
2300 }
2301
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002302 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
2303 if (mGlobalWifiRunning) {
2304 int N = oldWs.size();
2305 for (int i=0; i<N; i++) {
2306 getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked();
2307 }
2308 N = newWs.size();
2309 for (int i=0; i<N; i++) {
2310 getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked();
2311 }
2312 } else {
2313 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
2314 }
2315 }
2316
2317 public void noteWifiStoppedLocked(WorkSource ws) {
2318 if (mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002319 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002320 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
2321 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002322 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002323 mGlobalWifiRunning = false;
2324 mGlobalWifiRunningTimer.stopRunningLocked(this);
2325 int N = ws.size();
2326 for (int i=0; i<N; i++) {
2327 getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked();
2328 }
2329 } else {
2330 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002331 }
2332 }
2333
The Android Open Source Project10592532009-03-18 17:39:46 -07002334 public void noteBluetoothOnLocked() {
2335 if (!mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002336 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002337 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
2338 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002339 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002340 mBluetoothOn = true;
2341 mBluetoothOnTimer.startRunningLocked(this);
2342 }
2343 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002344
The Android Open Source Project10592532009-03-18 17:39:46 -07002345 public void noteBluetoothOffLocked() {
2346 if (mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002347 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002348 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
2349 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002350 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002351 mBluetoothOn = false;
2352 mBluetoothOnTimer.stopRunningLocked(this);
2353 }
2354 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002355
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002356 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002357
The Android Open Source Project10592532009-03-18 17:39:46 -07002358 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002359 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002360 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002361 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
2362 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002363 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002364 }
2365 mWifiFullLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002366 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002367 }
2368
2369 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002370 mWifiFullLockNesting--;
2371 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002372 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002373 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
2374 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002375 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002376 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002377 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002378 }
2379
Nick Pelly6ccaa542012-06-15 15:22:47 -07002380 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002381
Nick Pelly6ccaa542012-06-15 15:22:47 -07002382 public void noteWifiScanStartedLocked(int uid) {
2383 if (mWifiScanNesting == 0) {
2384 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
2385 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002386 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002387 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002388 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002389 mWifiScanNesting++;
2390 getUidStatsLocked(uid).noteWifiScanStartedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002391 }
2392
Nick Pelly6ccaa542012-06-15 15:22:47 -07002393 public void noteWifiScanStoppedLocked(int uid) {
2394 mWifiScanNesting--;
2395 if (mWifiScanNesting == 0) {
2396 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
2397 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002398 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002399 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002400 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002401 getUidStatsLocked(uid).noteWifiScanStoppedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002402 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002403
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002404 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002405
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002406 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002407 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002408 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002409 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
2410 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002411 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002412 }
2413 mWifiMulticastNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002414 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002415 }
2416
2417 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002418 mWifiMulticastNesting--;
2419 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002420 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002421 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
2422 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002423 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002424 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002425 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002426 }
2427
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002428 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2429 int N = ws.size();
2430 for (int i=0; i<N; i++) {
2431 noteFullWifiLockAcquiredLocked(ws.get(i));
2432 }
2433 }
2434
2435 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
2436 int N = ws.size();
2437 for (int i=0; i<N; i++) {
2438 noteFullWifiLockReleasedLocked(ws.get(i));
2439 }
2440 }
2441
Nick Pelly6ccaa542012-06-15 15:22:47 -07002442 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002443 int N = ws.size();
2444 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07002445 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002446 }
2447 }
2448
Nick Pelly6ccaa542012-06-15 15:22:47 -07002449 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002450 int N = ws.size();
2451 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07002452 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002453 }
2454 }
2455
2456 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
2457 int N = ws.size();
2458 for (int i=0; i<N; i++) {
2459 noteWifiMulticastEnabledLocked(ws.get(i));
2460 }
2461 }
2462
2463 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
2464 int N = ws.size();
2465 for (int i=0; i<N; i++) {
2466 noteWifiMulticastDisabledLocked(ws.get(i));
2467 }
2468 }
2469
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002470 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
2471 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
2472 mMobileIfaces.add(iface);
2473 } else {
2474 mMobileIfaces.remove(iface);
2475 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07002476 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
2477 mWifiIfaces.add(iface);
2478 } else {
2479 mWifiIfaces.remove(iface);
2480 }
2481 }
2482
2483 public void noteNetworkStatsEnabledLocked() {
2484 // During device boot, qtaguid isn't enabled until after the inital
2485 // loading of battery stats. Now that they're enabled, take our initial
2486 // snapshot for future delta calculation.
2487 updateNetworkActivityLocked();
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002488 }
2489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002491 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002492 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002493
Dianne Hackborn617f8772009-03-31 15:04:46 -07002494 @Override public long getScreenBrightnessTime(int brightnessBin,
2495 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002496 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07002497 batteryRealtime, which);
2498 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002499
Dianne Hackborn617f8772009-03-31 15:04:46 -07002500 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002501 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002502 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002504 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002505 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002507
Dianne Hackborn627bba72009-03-24 22:32:56 -07002508 @Override public long getPhoneSignalStrengthTime(int strengthBin,
2509 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002510 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002511 batteryRealtime, which);
2512 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002513
2514 @Override public long getPhoneSignalScanningTime(
2515 long batteryRealtime, int which) {
2516 return mPhoneSignalScanningTimer.getTotalTimeLocked(
2517 batteryRealtime, which);
2518 }
2519
Catherine Liufb900812012-07-17 14:12:56 -05002520 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
2521 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002522 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002523
Dianne Hackborn627bba72009-03-24 22:32:56 -07002524 @Override public long getPhoneDataConnectionTime(int dataType,
2525 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002526 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002527 batteryRealtime, which);
2528 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002529
Dianne Hackborn617f8772009-03-31 15:04:46 -07002530 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002531 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002532 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002533
The Android Open Source Project10592532009-03-18 17:39:46 -07002534 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002535 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002536 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002537
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002538 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) {
2539 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002540 }
2541
The Android Open Source Project10592532009-03-18 17:39:46 -07002542 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002543 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002544 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002545
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07002546 @Override
2547 public long getNetworkActivityCount(int type, int which) {
2548 if (type >= 0 && type < mNetworkActivityCounters.length) {
2549 return mNetworkActivityCounters[type].getCountLocked(which);
2550 } else {
2551 return 0;
2552 }
2553 }
2554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002555 @Override public boolean getIsOnBattery() {
2556 return mOnBattery;
2557 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002559 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
2560 return mUidStats;
2561 }
2562
2563 /**
2564 * The statistics associated with a particular uid.
2565 */
2566 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002569
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002570 boolean mWifiRunning;
2571 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002572
The Android Open Source Project10592532009-03-18 17:39:46 -07002573 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002574 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002575
Nick Pelly6ccaa542012-06-15 15:22:47 -07002576 boolean mWifiScanStarted;
2577 StopwatchTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002578
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002579 boolean mWifiMulticastEnabled;
2580 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002581
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002582 boolean mAudioTurnedOn;
2583 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002584
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002585 boolean mVideoTurnedOn;
2586 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002587
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002588 StopwatchTimer mForegroundActivityTimer;
2589
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002590 BatchTimer mVibratorOnTimer;
2591
Dianne Hackborn617f8772009-03-31 15:04:46 -07002592 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002593
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07002594 LongSamplingCounter[] mNetworkActivityCounters;
2595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002596 /**
2597 * The statistics we have collected for this uid's wake locks.
2598 */
2599 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
2600
2601 /**
2602 * The statistics we have collected for this uid's sensor activations.
2603 */
2604 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
2605
2606 /**
2607 * The statistics we have collected for this uid's processes.
2608 */
2609 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
2610
2611 /**
2612 * The statistics we have collected for this uid's processes.
2613 */
2614 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002615
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002616 /**
2617 * The transient wake stats we have collected for this uid's pids.
2618 */
2619 final SparseArray<Pid> mPids = new SparseArray<Pid>();
2620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 public Uid(int uid) {
2622 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002623 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2624 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002625 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002626 mFullWifiLockTimers, mUnpluggables);
Nick Pelly6ccaa542012-06-15 15:22:47 -07002627 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
2628 mWifiScanTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002629 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002630 mWifiMulticastTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002631 }
2632
2633 @Override
2634 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
2635 return mWakelockStats;
2636 }
2637
2638 @Override
2639 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
2640 return mSensorStats;
2641 }
2642
2643 @Override
2644 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
2645 return mProcessStats;
2646 }
2647
2648 @Override
2649 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
2650 return mPackageStats;
2651 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002652
2653 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 public int getUid() {
2655 return mUid;
2656 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002657
2658 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002659 public void noteWifiRunningLocked() {
2660 if (!mWifiRunning) {
2661 mWifiRunning = true;
2662 if (mWifiRunningTimer == null) {
2663 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2664 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002665 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002666 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002667 }
2668 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002669
Dianne Hackborn617f8772009-03-31 15:04:46 -07002670 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002671 public void noteWifiStoppedLocked() {
2672 if (mWifiRunning) {
2673 mWifiRunning = false;
2674 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002675 }
2676 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002677
Dianne Hackborn617f8772009-03-31 15:04:46 -07002678 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002679 public void noteFullWifiLockAcquiredLocked() {
2680 if (!mFullWifiLockOut) {
2681 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002682 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002683 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002684 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002685 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002686 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2687 }
2688 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002689
The Android Open Source Project10592532009-03-18 17:39:46 -07002690 @Override
2691 public void noteFullWifiLockReleasedLocked() {
2692 if (mFullWifiLockOut) {
2693 mFullWifiLockOut = false;
2694 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2695 }
2696 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002697
The Android Open Source Project10592532009-03-18 17:39:46 -07002698 @Override
Nick Pelly6ccaa542012-06-15 15:22:47 -07002699 public void noteWifiScanStartedLocked() {
2700 if (!mWifiScanStarted) {
2701 mWifiScanStarted = true;
2702 if (mWifiScanTimer == null) {
2703 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
2704 mWifiScanTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002705 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002706 mWifiScanTimer.startRunningLocked(BatteryStatsImpl.this);
The Android Open Source Project10592532009-03-18 17:39:46 -07002707 }
2708 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002709
The Android Open Source Project10592532009-03-18 17:39:46 -07002710 @Override
Nick Pelly6ccaa542012-06-15 15:22:47 -07002711 public void noteWifiScanStoppedLocked() {
2712 if (mWifiScanStarted) {
2713 mWifiScanStarted = false;
2714 mWifiScanTimer.stopRunningLocked(BatteryStatsImpl.this);
The Android Open Source Project10592532009-03-18 17:39:46 -07002715 }
2716 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002717
2718 @Override
2719 public void noteWifiMulticastEnabledLocked() {
2720 if (!mWifiMulticastEnabled) {
2721 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002722 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002723 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002724 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002725 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002726 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
2727 }
2728 }
2729
2730 @Override
2731 public void noteWifiMulticastDisabledLocked() {
2732 if (mWifiMulticastEnabled) {
2733 mWifiMulticastEnabled = false;
2734 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
2735 }
2736 }
2737
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002738 public StopwatchTimer createAudioTurnedOnTimerLocked() {
2739 if (mAudioTurnedOnTimer == null) {
2740 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
2741 null, mUnpluggables);
2742 }
2743 return mAudioTurnedOnTimer;
2744 }
2745
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002746 @Override
2747 public void noteAudioTurnedOnLocked() {
2748 if (!mAudioTurnedOn) {
2749 mAudioTurnedOn = true;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002750 createAudioTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002751 }
2752 }
2753
2754 @Override
2755 public void noteAudioTurnedOffLocked() {
2756 if (mAudioTurnedOn) {
2757 mAudioTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002758 if (mAudioTurnedOnTimer != null) {
2759 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2760 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002761 }
2762 }
2763
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002764 public StopwatchTimer createVideoTurnedOnTimerLocked() {
2765 if (mVideoTurnedOnTimer == null) {
2766 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
2767 null, mUnpluggables);
2768 }
2769 return mVideoTurnedOnTimer;
2770 }
2771
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002772 @Override
2773 public void noteVideoTurnedOnLocked() {
2774 if (!mVideoTurnedOn) {
2775 mVideoTurnedOn = true;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002776 createVideoTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002777 }
2778 }
2779
2780 @Override
2781 public void noteVideoTurnedOffLocked() {
2782 if (mVideoTurnedOn) {
2783 mVideoTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002784 if (mVideoTurnedOnTimer != null) {
2785 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2786 }
2787 }
2788 }
2789
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002790 public StopwatchTimer createForegroundActivityTimerLocked() {
2791 if (mForegroundActivityTimer == null) {
2792 mForegroundActivityTimer = new StopwatchTimer(
2793 Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables);
2794 }
2795 return mForegroundActivityTimer;
2796 }
2797
2798 @Override
2799 public void noteActivityResumedLocked() {
2800 // We always start, since we want multiple foreground PIDs to nest
2801 createForegroundActivityTimerLocked().startRunningLocked(BatteryStatsImpl.this);
2802 }
2803
2804 @Override
2805 public void noteActivityPausedLocked() {
2806 if (mForegroundActivityTimer != null) {
2807 mForegroundActivityTimer.stopRunningLocked(BatteryStatsImpl.this);
2808 }
2809 }
2810
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002811 public BatchTimer createVibratorOnTimerLocked() {
2812 if (mVibratorOnTimer == null) {
2813 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
2814 mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal);
2815 }
2816 return mVibratorOnTimer;
2817 }
2818
2819 public void noteVibratorOnLocked(long durationMillis) {
2820 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
2821 }
2822
2823 public void noteVibratorOffLocked() {
2824 if (mVibratorOnTimer != null) {
2825 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002826 }
2827 }
2828
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002829 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002830 public long getWifiRunningTime(long batteryRealtime, int which) {
2831 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002832 return 0;
2833 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002834 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002835 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002836
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002837 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002838 public long getFullWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002839 if (mFullWifiLockTimer == null) {
2840 return 0;
2841 }
Evan Millarc64edde2009-04-18 12:26:32 -07002842 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002843 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002844
2845 @Override
Nick Pelly6ccaa542012-06-15 15:22:47 -07002846 public long getWifiScanTime(long batteryRealtime, int which) {
2847 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002848 return 0;
2849 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002850 return mWifiScanTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002851 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002852
2853 @Override
2854 public long getWifiMulticastTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002855 if (mWifiMulticastTimer == null) {
2856 return 0;
2857 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002858 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
2859 which);
2860 }
2861
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002862 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002863 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
2864 if (mAudioTurnedOnTimer == null) {
2865 return 0;
2866 }
2867 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2868 }
2869
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002870 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002871 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
2872 if (mVideoTurnedOnTimer == null) {
2873 return 0;
2874 }
2875 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2876 }
2877
Dianne Hackborn617f8772009-03-31 15:04:46 -07002878 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002879 public Timer getForegroundActivityTimer() {
2880 return mForegroundActivityTimer;
2881 }
2882
2883 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002884 public Timer getVibratorOnTimer() {
2885 return mVibratorOnTimer;
2886 }
2887
2888 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07002889 public void noteUserActivityLocked(int type) {
2890 if (mUserActivityCounters == null) {
2891 initUserActivityLocked();
2892 }
Jeff Browndf693de2012-07-27 12:03:38 -07002893 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
2894 mUserActivityCounters[type].stepAtomic();
2895 } else {
2896 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
2897 new Throwable());
2898 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002899 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002900
Dianne Hackborn617f8772009-03-31 15:04:46 -07002901 @Override
2902 public boolean hasUserActivity() {
2903 return mUserActivityCounters != null;
2904 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002905
Dianne Hackborn617f8772009-03-31 15:04:46 -07002906 @Override
2907 public int getUserActivityCount(int type, int which) {
2908 if (mUserActivityCounters == null) {
2909 return 0;
2910 }
Evan Millarc64edde2009-04-18 12:26:32 -07002911 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002912 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002913
Dianne Hackborn617f8772009-03-31 15:04:46 -07002914 void initUserActivityLocked() {
2915 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2916 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2917 mUserActivityCounters[i] = new Counter(mUnpluggables);
2918 }
2919 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002920
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07002921 void noteNetworkActivityLocked(int type, long delta) {
2922 if (mNetworkActivityCounters == null) {
2923 initNetworkActivityLocked();
2924 }
2925 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
2926 mNetworkActivityCounters[type].addCountLocked(delta);
2927 } else {
2928 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
2929 new Throwable());
2930 }
2931 }
2932
2933 @Override
2934 public boolean hasNetworkActivity() {
2935 return mNetworkActivityCounters != null;
2936 }
2937
2938 @Override
2939 public long getNetworkActivityCount(int type, int which) {
2940 if (mNetworkActivityCounters != null && type >= 0
2941 && type < mNetworkActivityCounters.length) {
2942 return mNetworkActivityCounters[type].getCountLocked(which);
2943 } else {
2944 return 0;
2945 }
2946 }
2947
2948 void initNetworkActivityLocked() {
2949 mNetworkActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
2950 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
2951 mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
2952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002953 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002954
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002955 /**
2956 * Clear all stats for this uid. Returns true if the uid is completely
2957 * inactive so can be dropped.
2958 */
2959 boolean reset() {
2960 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002961
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002962 if (mWifiRunningTimer != null) {
2963 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false);
2964 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002965 }
2966 if (mFullWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002967 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002968 active |= mFullWifiLockOut;
2969 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002970 if (mWifiScanTimer != null) {
2971 active |= !mWifiScanTimer.reset(BatteryStatsImpl.this, false);
2972 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002973 }
2974 if (mWifiMulticastTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002975 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002976 active |= mWifiMulticastEnabled;
2977 }
2978 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002979 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002980 active |= mAudioTurnedOn;
2981 }
2982 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002983 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002984 active |= mVideoTurnedOn;
2985 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002986 if (mForegroundActivityTimer != null) {
2987 active |= !mForegroundActivityTimer.reset(BatteryStatsImpl.this, false);
2988 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002989 if (mVibratorOnTimer != null) {
2990 if (mVibratorOnTimer.reset(BatteryStatsImpl.this, false)) {
2991 mVibratorOnTimer.detach();
2992 mVibratorOnTimer = null;
2993 } else {
2994 active = true;
2995 }
2996 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002997
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002998 if (mUserActivityCounters != null) {
2999 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3000 mUserActivityCounters[i].reset(false);
3001 }
3002 }
3003
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003004 if (mNetworkActivityCounters != null) {
3005 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
3006 mNetworkActivityCounters[i].reset(false);
3007 }
3008 }
3009
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003010 if (mWakelockStats.size() > 0) {
3011 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
3012 while (it.hasNext()) {
3013 Map.Entry<String, Wakelock> wakelockEntry = it.next();
3014 Wakelock wl = wakelockEntry.getValue();
3015 if (wl.reset()) {
3016 it.remove();
3017 } else {
3018 active = true;
3019 }
3020 }
3021 }
3022 if (mSensorStats.size() > 0) {
3023 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
3024 while (it.hasNext()) {
3025 Map.Entry<Integer, Sensor> sensorEntry = it.next();
3026 Sensor s = sensorEntry.getValue();
3027 if (s.reset()) {
3028 it.remove();
3029 } else {
3030 active = true;
3031 }
3032 }
3033 }
3034 if (mProcessStats.size() > 0) {
3035 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
3036 while (it.hasNext()) {
3037 Map.Entry<String, Proc> procEntry = it.next();
3038 procEntry.getValue().detach();
3039 }
3040 mProcessStats.clear();
3041 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003042 if (mPids.size() > 0) {
3043 for (int i=0; !active && i<mPids.size(); i++) {
3044 Pid pid = mPids.valueAt(i);
3045 if (pid.mWakeStart != 0) {
3046 active = true;
3047 }
3048 }
3049 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003050 if (mPackageStats.size() > 0) {
3051 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
3052 while (it.hasNext()) {
3053 Map.Entry<String, Pkg> pkgEntry = it.next();
3054 Pkg p = pkgEntry.getValue();
3055 p.detach();
3056 if (p.mServiceStats.size() > 0) {
3057 Iterator<Map.Entry<String, Pkg.Serv>> it2
3058 = p.mServiceStats.entrySet().iterator();
3059 while (it2.hasNext()) {
3060 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
3061 servEntry.getValue().detach();
3062 }
3063 }
3064 }
3065 mPackageStats.clear();
3066 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003067
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003068 mPids.clear();
3069
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003070 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003071 if (mWifiRunningTimer != null) {
3072 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003073 }
3074 if (mFullWifiLockTimer != null) {
3075 mFullWifiLockTimer.detach();
3076 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003077 if (mWifiScanTimer != null) {
3078 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003079 }
3080 if (mWifiMulticastTimer != null) {
3081 mWifiMulticastTimer.detach();
3082 }
3083 if (mAudioTurnedOnTimer != null) {
3084 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003085 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003086 }
3087 if (mVideoTurnedOnTimer != null) {
3088 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003089 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003090 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003091 if (mForegroundActivityTimer != null) {
3092 mForegroundActivityTimer.detach();
3093 mForegroundActivityTimer = null;
3094 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003095 if (mUserActivityCounters != null) {
3096 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3097 mUserActivityCounters[i].detach();
3098 }
3099 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003100 if (mNetworkActivityCounters != null) {
3101 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
3102 mNetworkActivityCounters[i].detach();
3103 }
3104 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003105 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003106
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003107 return !active;
3108 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003110 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3111 out.writeInt(mWakelockStats.size());
3112 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
3113 out.writeString(wakelockEntry.getKey());
3114 Uid.Wakelock wakelock = wakelockEntry.getValue();
3115 wakelock.writeToParcelLocked(out, batteryRealtime);
3116 }
3117
3118 out.writeInt(mSensorStats.size());
3119 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
3120 out.writeInt(sensorEntry.getKey());
3121 Uid.Sensor sensor = sensorEntry.getValue();
3122 sensor.writeToParcelLocked(out, batteryRealtime);
3123 }
3124
3125 out.writeInt(mProcessStats.size());
3126 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
3127 out.writeString(procEntry.getKey());
3128 Uid.Proc proc = procEntry.getValue();
3129 proc.writeToParcelLocked(out);
3130 }
3131
3132 out.writeInt(mPackageStats.size());
3133 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
3134 out.writeString(pkgEntry.getKey());
3135 Uid.Pkg pkg = pkgEntry.getValue();
3136 pkg.writeToParcelLocked(out);
3137 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003138
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003139 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003140 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003141 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003142 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003143 out.writeInt(0);
3144 }
3145 if (mFullWifiLockTimer != null) {
3146 out.writeInt(1);
3147 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
3148 } else {
3149 out.writeInt(0);
3150 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003151 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003152 out.writeInt(1);
Nick Pelly6ccaa542012-06-15 15:22:47 -07003153 mWifiScanTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003154 } else {
3155 out.writeInt(0);
3156 }
3157 if (mWifiMulticastTimer != null) {
3158 out.writeInt(1);
3159 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
3160 } else {
3161 out.writeInt(0);
3162 }
3163 if (mAudioTurnedOnTimer != null) {
3164 out.writeInt(1);
3165 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
3166 } else {
3167 out.writeInt(0);
3168 }
3169 if (mVideoTurnedOnTimer != null) {
3170 out.writeInt(1);
3171 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
3172 } else {
3173 out.writeInt(0);
3174 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003175 if (mForegroundActivityTimer != null) {
3176 out.writeInt(1);
3177 mForegroundActivityTimer.writeToParcel(out, batteryRealtime);
3178 } else {
3179 out.writeInt(0);
3180 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003181 if (mVibratorOnTimer != null) {
3182 out.writeInt(1);
3183 mVibratorOnTimer.writeToParcel(out, batteryRealtime);
3184 } else {
3185 out.writeInt(0);
3186 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003187 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003188 out.writeInt(1);
3189 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3190 mUserActivityCounters[i].writeToParcel(out);
3191 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003192 } else {
3193 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003194 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003195 if (mNetworkActivityCounters != null) {
3196 out.writeInt(1);
3197 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
3198 mNetworkActivityCounters[i].writeToParcel(out);
3199 }
3200 } else {
3201 out.writeInt(0);
3202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003203 }
3204
3205 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3206 int numWakelocks = in.readInt();
3207 mWakelockStats.clear();
3208 for (int j = 0; j < numWakelocks; j++) {
3209 String wakelockName = in.readString();
3210 Uid.Wakelock wakelock = new Wakelock();
3211 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackbornc24ab862011-10-18 15:55:03 -07003212 // We will just drop some random set of wakelocks if
3213 // the previous run of the system was an older version
3214 // that didn't impose a limit.
3215 mWakelockStats.put(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003216 }
3217
3218 int numSensors = in.readInt();
3219 mSensorStats.clear();
3220 for (int k = 0; k < numSensors; k++) {
3221 int sensorNumber = in.readInt();
3222 Uid.Sensor sensor = new Sensor(sensorNumber);
3223 sensor.readFromParcelLocked(mUnpluggables, in);
3224 mSensorStats.put(sensorNumber, sensor);
3225 }
3226
3227 int numProcs = in.readInt();
3228 mProcessStats.clear();
3229 for (int k = 0; k < numProcs; k++) {
3230 String processName = in.readString();
3231 Uid.Proc proc = new Proc();
3232 proc.readFromParcelLocked(in);
3233 mProcessStats.put(processName, proc);
3234 }
3235
3236 int numPkgs = in.readInt();
3237 mPackageStats.clear();
3238 for (int l = 0; l < numPkgs; l++) {
3239 String packageName = in.readString();
3240 Uid.Pkg pkg = new Pkg();
3241 pkg.readFromParcelLocked(in);
3242 mPackageStats.put(packageName, pkg);
3243 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003244
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003245 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003246 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003247 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
3248 mWifiRunningTimers, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003249 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003250 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003251 }
3252 mFullWifiLockOut = false;
3253 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003254 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003255 mFullWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003256 } else {
3257 mFullWifiLockTimer = null;
3258 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003259 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003260 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003261 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
3262 mWifiScanTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003263 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003264 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003265 }
3266 mWifiMulticastEnabled = false;
3267 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003268 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003269 mWifiMulticastTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003270 } else {
3271 mWifiMulticastTimer = null;
3272 }
3273 mAudioTurnedOn = false;
3274 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003275 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003276 null, mUnpluggables, in);
3277 } else {
3278 mAudioTurnedOnTimer = null;
3279 }
3280 mVideoTurnedOn = false;
3281 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003282 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003283 null, mUnpluggables, in);
3284 } else {
3285 mVideoTurnedOnTimer = null;
3286 }
3287 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003288 mForegroundActivityTimer = new StopwatchTimer(
3289 Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables, in);
3290 } else {
3291 mForegroundActivityTimer = null;
3292 }
3293 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003294 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
3295 mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal, in);
3296 } else {
3297 mVibratorOnTimer = null;
3298 }
3299 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003300 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
3301 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3302 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
3303 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003304 } else {
3305 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07003306 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003307 if (in.readInt() != 0) {
3308 mNetworkActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
3309 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
3310 mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
3311 }
3312 } else {
3313 mNetworkActivityCounters = null;
3314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 }
3316
3317 /**
3318 * The statistics associated with a particular wake lock.
3319 */
3320 public final class Wakelock extends BatteryStats.Uid.Wakelock {
3321 /**
3322 * How long (in ms) this uid has been keeping the device partially awake.
3323 */
Evan Millarc64edde2009-04-18 12:26:32 -07003324 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325
3326 /**
3327 * How long (in ms) this uid has been keeping the device fully awake.
3328 */
Evan Millarc64edde2009-04-18 12:26:32 -07003329 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003330
3331 /**
3332 * How long (in ms) this uid has had a window keeping the device awake.
3333 */
Evan Millarc64edde2009-04-18 12:26:32 -07003334 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335
3336 /**
3337 * Reads a possibly null Timer from a Parcel. The timer is associated with the
3338 * proper timer pool from the given BatteryStatsImpl object.
3339 *
3340 * @param in the Parcel to be read from.
3341 * return a new Timer, or null.
3342 */
Evan Millarc64edde2009-04-18 12:26:32 -07003343 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344 ArrayList<Unpluggable> unpluggables, Parcel in) {
3345 if (in.readInt() == 0) {
3346 return null;
3347 }
3348
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003349 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003350 }
3351
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003352 boolean reset() {
3353 boolean wlactive = false;
3354 if (mTimerFull != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003355 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003356 }
3357 if (mTimerPartial != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003358 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003359 }
3360 if (mTimerWindow != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003361 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003362 }
3363 if (!wlactive) {
3364 if (mTimerFull != null) {
3365 mTimerFull.detach();
3366 mTimerFull = null;
3367 }
3368 if (mTimerPartial != null) {
3369 mTimerPartial.detach();
3370 mTimerPartial = null;
3371 }
3372 if (mTimerWindow != null) {
3373 mTimerWindow.detach();
3374 mTimerWindow = null;
3375 }
3376 }
3377 return !wlactive;
3378 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3381 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
3382 mPartialTimers, unpluggables, in);
3383 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
3384 mFullTimers, unpluggables, in);
3385 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
3386 mWindowTimers, unpluggables, in);
3387 }
3388
3389 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3390 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
3391 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
3392 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
3393 }
3394
3395 @Override
3396 public Timer getWakeTime(int type) {
3397 switch (type) {
3398 case WAKE_TYPE_FULL: return mTimerFull;
3399 case WAKE_TYPE_PARTIAL: return mTimerPartial;
3400 case WAKE_TYPE_WINDOW: return mTimerWindow;
3401 default: throw new IllegalArgumentException("type = " + type);
3402 }
3403 }
3404 }
3405
3406 public final class Sensor extends BatteryStats.Uid.Sensor {
3407 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07003408 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 public Sensor(int handle) {
3411 mHandle = handle;
3412 }
3413
Evan Millarc64edde2009-04-18 12:26:32 -07003414 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003415 Parcel in) {
3416 if (in.readInt() == 0) {
3417 return null;
3418 }
3419
Evan Millarc64edde2009-04-18 12:26:32 -07003420 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003421 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003422 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003423 mSensorTimers.put(mHandle, pool);
3424 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003425 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003426 }
3427
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003428 boolean reset() {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003429 if (mTimer.reset(BatteryStatsImpl.this, true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003430 mTimer = null;
3431 return true;
3432 }
3433 return false;
3434 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003436 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3437 mTimer = readTimerFromParcel(unpluggables, in);
3438 }
3439
3440 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3441 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
3442 }
3443
3444 @Override
3445 public Timer getSensorTime() {
3446 return mTimer;
3447 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003448
3449 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003450 public int getHandle() {
3451 return mHandle;
3452 }
3453 }
3454
3455 /**
3456 * The statistics associated with a particular process.
3457 */
3458 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
3459 /**
3460 * Total time (in 1/100 sec) spent executing in user code.
3461 */
3462 long mUserTime;
3463
3464 /**
3465 * Total time (in 1/100 sec) spent executing in kernel code.
3466 */
3467 long mSystemTime;
3468
3469 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003470 * Amount of time the process was running in the foreground.
3471 */
3472 long mForegroundTime;
3473
3474 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003475 * Number of times the process has been started.
3476 */
3477 int mStarts;
3478
3479 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003480 * The amount of user time loaded from a previous save.
3481 */
3482 long mLoadedUserTime;
3483
3484 /**
3485 * The amount of system time loaded from a previous save.
3486 */
3487 long mLoadedSystemTime;
3488
3489 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003490 * The amount of foreground time loaded from a previous save.
3491 */
3492 long mLoadedForegroundTime;
3493
3494 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003495 * The number of times the process has started from a previous save.
3496 */
3497 int mLoadedStarts;
3498
3499 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 * The amount of user time loaded from the previous run.
3501 */
3502 long mLastUserTime;
3503
3504 /**
3505 * The amount of system time loaded from the previous run.
3506 */
3507 long mLastSystemTime;
3508
3509 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003510 * The amount of foreground time loaded from the previous run
3511 */
3512 long mLastForegroundTime;
3513
3514 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003515 * The number of times the process has started from the previous run.
3516 */
3517 int mLastStarts;
3518
3519 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 * The amount of user time when last unplugged.
3521 */
3522 long mUnpluggedUserTime;
3523
3524 /**
3525 * The amount of system time when last unplugged.
3526 */
3527 long mUnpluggedSystemTime;
3528
3529 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003530 * The amount of foreground time since unplugged.
3531 */
3532 long mUnpluggedForegroundTime;
3533
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003534 /**
3535 * The number of times the process has started before unplugged.
3536 */
3537 int mUnpluggedStarts;
3538
Amith Yamasanie43530a2009-08-21 13:11:37 -07003539 SamplingCounter[] mSpeedBins;
3540
Dianne Hackborn287952c2010-09-22 22:34:31 -07003541 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 Proc() {
3544 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003545 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003546 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003547
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003548 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 mUnpluggedUserTime = mUserTime;
3550 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003551 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003552 mUnpluggedStarts = mStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003553 }
3554
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003555 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003556 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003557
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003558 void detach() {
3559 mUnpluggables.remove(this);
3560 for (int i = 0; i < mSpeedBins.length; i++) {
3561 SamplingCounter c = mSpeedBins[i];
3562 if (c != null) {
3563 mUnpluggables.remove(c);
3564 mSpeedBins[i] = null;
3565 }
3566 }
3567 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003568
Dianne Hackborn287952c2010-09-22 22:34:31 -07003569 public int countExcessivePowers() {
3570 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003571 }
3572
Dianne Hackborn287952c2010-09-22 22:34:31 -07003573 public ExcessivePower getExcessivePower(int i) {
3574 if (mExcessivePower != null) {
3575 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003576 }
3577 return null;
3578 }
3579
3580 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003581 if (mExcessivePower == null) {
3582 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003583 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07003584 ExcessivePower ew = new ExcessivePower();
3585 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003586 ew.overTime = overTime;
3587 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07003588 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003589 }
3590
Dianne Hackborn287952c2010-09-22 22:34:31 -07003591 public void addExcessiveCpu(long overTime, long usedTime) {
3592 if (mExcessivePower == null) {
3593 mExcessivePower = new ArrayList<ExcessivePower>();
3594 }
3595 ExcessivePower ew = new ExcessivePower();
3596 ew.type = ExcessivePower.TYPE_CPU;
3597 ew.overTime = overTime;
3598 ew.usedTime = usedTime;
3599 mExcessivePower.add(ew);
3600 }
3601
3602 void writeExcessivePowerToParcelLocked(Parcel out) {
3603 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003604 out.writeInt(0);
3605 return;
3606 }
3607
Dianne Hackborn287952c2010-09-22 22:34:31 -07003608 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003609 out.writeInt(N);
3610 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003611 ExcessivePower ew = mExcessivePower.get(i);
3612 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003613 out.writeLong(ew.overTime);
3614 out.writeLong(ew.usedTime);
3615 }
3616 }
3617
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003618 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003619 final int N = in.readInt();
3620 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003621 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003622 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003623 }
3624
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003625 if (N > 10000) {
3626 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
3627 return false;
3628 }
3629
Dianne Hackborn287952c2010-09-22 22:34:31 -07003630 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003631 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003632 ExcessivePower ew = new ExcessivePower();
3633 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003634 ew.overTime = in.readLong();
3635 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07003636 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003637 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003638 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003639 }
3640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 void writeToParcelLocked(Parcel out) {
3642 out.writeLong(mUserTime);
3643 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003644 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645 out.writeInt(mStarts);
3646 out.writeLong(mLoadedUserTime);
3647 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003648 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003649 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003650 out.writeLong(mUnpluggedUserTime);
3651 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003652 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003653 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003654
3655 out.writeInt(mSpeedBins.length);
3656 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003657 SamplingCounter c = mSpeedBins[i];
3658 if (c != null) {
3659 out.writeInt(1);
3660 c.writeToParcel(out);
3661 } else {
3662 out.writeInt(0);
3663 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003664 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003665
Dianne Hackborn287952c2010-09-22 22:34:31 -07003666 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667 }
3668
3669 void readFromParcelLocked(Parcel in) {
3670 mUserTime = in.readLong();
3671 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003672 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003673 mStarts = in.readInt();
3674 mLoadedUserTime = in.readLong();
3675 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003676 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003678 mLastUserTime = 0;
3679 mLastSystemTime = 0;
3680 mLastForegroundTime = 0;
3681 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003682 mUnpluggedUserTime = in.readLong();
3683 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003684 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07003686
3687 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003688 int steps = getCpuSpeedSteps();
3689 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07003690 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003691 if (in.readInt() != 0) {
3692 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
3693 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003694 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003695
Dianne Hackborn287952c2010-09-22 22:34:31 -07003696 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 }
3698
3699 public BatteryStatsImpl getBatteryStats() {
3700 return BatteryStatsImpl.this;
3701 }
3702
3703 public void addCpuTimeLocked(int utime, int stime) {
3704 mUserTime += utime;
3705 mSystemTime += stime;
3706 }
3707
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003708 public void addForegroundTimeLocked(long ttime) {
3709 mForegroundTime += ttime;
3710 }
3711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003712 public void incStartsLocked() {
3713 mStarts++;
3714 }
3715
3716 @Override
3717 public long getUserTime(int which) {
3718 long val;
3719 if (which == STATS_LAST) {
3720 val = mLastUserTime;
3721 } else {
3722 val = mUserTime;
3723 if (which == STATS_CURRENT) {
3724 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003725 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003726 val -= mUnpluggedUserTime;
3727 }
3728 }
3729 return val;
3730 }
3731
3732 @Override
3733 public long getSystemTime(int which) {
3734 long val;
3735 if (which == STATS_LAST) {
3736 val = mLastSystemTime;
3737 } else {
3738 val = mSystemTime;
3739 if (which == STATS_CURRENT) {
3740 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003741 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003742 val -= mUnpluggedSystemTime;
3743 }
3744 }
3745 return val;
3746 }
3747
3748 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003749 public long getForegroundTime(int which) {
3750 long val;
3751 if (which == STATS_LAST) {
3752 val = mLastForegroundTime;
3753 } else {
3754 val = mForegroundTime;
3755 if (which == STATS_CURRENT) {
3756 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003757 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003758 val -= mUnpluggedForegroundTime;
3759 }
3760 }
3761 return val;
3762 }
3763
3764 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003765 public int getStarts(int which) {
3766 int val;
3767 if (which == STATS_LAST) {
3768 val = mLastStarts;
3769 } else {
3770 val = mStarts;
3771 if (which == STATS_CURRENT) {
3772 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003773 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003774 val -= mUnpluggedStarts;
3775 }
3776 }
3777 return val;
3778 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003779
3780 /* Called by ActivityManagerService when CPU times are updated. */
3781 public void addSpeedStepTimes(long[] values) {
3782 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003783 long amt = values[i];
3784 if (amt != 0) {
3785 SamplingCounter c = mSpeedBins[i];
3786 if (c == null) {
3787 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
3788 }
3789 c.addCountAtomic(values[i]);
3790 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003791 }
3792 }
3793
3794 @Override
3795 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
3796 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003797 SamplingCounter c = mSpeedBins[speedStep];
3798 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07003799 } else {
3800 return 0;
3801 }
3802 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003803 }
3804
3805 /**
3806 * The statistics associated with a particular package.
3807 */
3808 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
3809 /**
3810 * Number of times this package has done something that could wake up the
3811 * device from sleep.
3812 */
3813 int mWakeups;
3814
3815 /**
3816 * Number of things that could wake up the device loaded from a
3817 * previous save.
3818 */
3819 int mLoadedWakeups;
3820
3821 /**
3822 * Number of things that could wake up the device as of the
3823 * last run.
3824 */
3825 int mLastWakeups;
3826
3827 /**
3828 * Number of things that could wake up the device as of the
3829 * last run.
3830 */
3831 int mUnpluggedWakeups;
3832
3833 /**
3834 * The statics we have collected for this package's services.
3835 */
3836 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
3837
3838 Pkg() {
3839 mUnpluggables.add(this);
3840 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003841
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003842 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003843 mUnpluggedWakeups = mWakeups;
3844 }
3845
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003846 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003847 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003848
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003849 void detach() {
3850 mUnpluggables.remove(this);
3851 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003853 void readFromParcelLocked(Parcel in) {
3854 mWakeups = in.readInt();
3855 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003856 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003857 mUnpluggedWakeups = in.readInt();
3858
3859 int numServs = in.readInt();
3860 mServiceStats.clear();
3861 for (int m = 0; m < numServs; m++) {
3862 String serviceName = in.readString();
3863 Uid.Pkg.Serv serv = new Serv();
3864 mServiceStats.put(serviceName, serv);
3865
3866 serv.readFromParcelLocked(in);
3867 }
3868 }
3869
3870 void writeToParcelLocked(Parcel out) {
3871 out.writeInt(mWakeups);
3872 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003873 out.writeInt(mUnpluggedWakeups);
3874
3875 out.writeInt(mServiceStats.size());
3876 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
3877 out.writeString(servEntry.getKey());
3878 Uid.Pkg.Serv serv = servEntry.getValue();
3879
3880 serv.writeToParcelLocked(out);
3881 }
3882 }
3883
3884 @Override
3885 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
3886 return mServiceStats;
3887 }
3888
3889 @Override
3890 public int getWakeups(int which) {
3891 int val;
3892 if (which == STATS_LAST) {
3893 val = mLastWakeups;
3894 } else {
3895 val = mWakeups;
3896 if (which == STATS_CURRENT) {
3897 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003898 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 val -= mUnpluggedWakeups;
3900 }
3901 }
3902
3903 return val;
3904 }
3905
3906 /**
3907 * The statistics associated with a particular service.
3908 */
3909 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
3910 /**
3911 * Total time (ms in battery uptime) the service has been left started.
3912 */
3913 long mStartTime;
3914
3915 /**
3916 * If service has been started and not yet stopped, this is
3917 * when it was started.
3918 */
3919 long mRunningSince;
3920
3921 /**
3922 * True if we are currently running.
3923 */
3924 boolean mRunning;
3925
3926 /**
3927 * Total number of times startService() has been called.
3928 */
3929 int mStarts;
3930
3931 /**
3932 * Total time (ms in battery uptime) the service has been left launched.
3933 */
3934 long mLaunchedTime;
3935
3936 /**
3937 * If service has been launched and not yet exited, this is
3938 * when it was launched (ms in battery uptime).
3939 */
3940 long mLaunchedSince;
3941
3942 /**
3943 * True if we are currently launched.
3944 */
3945 boolean mLaunched;
3946
3947 /**
3948 * Total number times the service has been launched.
3949 */
3950 int mLaunches;
3951
3952 /**
3953 * The amount of time spent started loaded from a previous save
3954 * (ms in battery uptime).
3955 */
3956 long mLoadedStartTime;
3957
3958 /**
3959 * The number of starts loaded from a previous save.
3960 */
3961 int mLoadedStarts;
3962
3963 /**
3964 * The number of launches loaded from a previous save.
3965 */
3966 int mLoadedLaunches;
3967
3968 /**
3969 * The amount of time spent started as of the last run (ms
3970 * in battery uptime).
3971 */
3972 long mLastStartTime;
3973
3974 /**
3975 * The number of starts as of the last run.
3976 */
3977 int mLastStarts;
3978
3979 /**
3980 * The number of launches as of the last run.
3981 */
3982 int mLastLaunches;
3983
3984 /**
3985 * The amount of time spent started when last unplugged (ms
3986 * in battery uptime).
3987 */
3988 long mUnpluggedStartTime;
3989
3990 /**
3991 * The number of starts when last unplugged.
3992 */
3993 int mUnpluggedStarts;
3994
3995 /**
3996 * The number of launches when last unplugged.
3997 */
3998 int mUnpluggedLaunches;
3999
4000 Serv() {
4001 mUnpluggables.add(this);
4002 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004003
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004004 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004005 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
4006 mUnpluggedStarts = mStarts;
4007 mUnpluggedLaunches = mLaunches;
4008 }
4009
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004010 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004012
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004013 void detach() {
4014 mUnpluggables.remove(this);
4015 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004017 void readFromParcelLocked(Parcel in) {
4018 mStartTime = in.readLong();
4019 mRunningSince = in.readLong();
4020 mRunning = in.readInt() != 0;
4021 mStarts = in.readInt();
4022 mLaunchedTime = in.readLong();
4023 mLaunchedSince = in.readLong();
4024 mLaunched = in.readInt() != 0;
4025 mLaunches = in.readInt();
4026 mLoadedStartTime = in.readLong();
4027 mLoadedStarts = in.readInt();
4028 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004029 mLastStartTime = 0;
4030 mLastStarts = 0;
4031 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004032 mUnpluggedStartTime = in.readLong();
4033 mUnpluggedStarts = in.readInt();
4034 mUnpluggedLaunches = in.readInt();
4035 }
4036
4037 void writeToParcelLocked(Parcel out) {
4038 out.writeLong(mStartTime);
4039 out.writeLong(mRunningSince);
4040 out.writeInt(mRunning ? 1 : 0);
4041 out.writeInt(mStarts);
4042 out.writeLong(mLaunchedTime);
4043 out.writeLong(mLaunchedSince);
4044 out.writeInt(mLaunched ? 1 : 0);
4045 out.writeInt(mLaunches);
4046 out.writeLong(mLoadedStartTime);
4047 out.writeInt(mLoadedStarts);
4048 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 out.writeLong(mUnpluggedStartTime);
4050 out.writeInt(mUnpluggedStarts);
4051 out.writeInt(mUnpluggedLaunches);
4052 }
4053
4054 long getLaunchTimeToNowLocked(long batteryUptime) {
4055 if (!mLaunched) return mLaunchedTime;
4056 return mLaunchedTime + batteryUptime - mLaunchedSince;
4057 }
4058
4059 long getStartTimeToNowLocked(long batteryUptime) {
4060 if (!mRunning) return mStartTime;
4061 return mStartTime + batteryUptime - mRunningSince;
4062 }
4063
4064 public void startLaunchedLocked() {
4065 if (!mLaunched) {
4066 mLaunches++;
4067 mLaunchedSince = getBatteryUptimeLocked();
4068 mLaunched = true;
4069 }
4070 }
4071
4072 public void stopLaunchedLocked() {
4073 if (mLaunched) {
4074 long time = getBatteryUptimeLocked() - mLaunchedSince;
4075 if (time > 0) {
4076 mLaunchedTime += time;
4077 } else {
4078 mLaunches--;
4079 }
4080 mLaunched = false;
4081 }
4082 }
4083
4084 public void startRunningLocked() {
4085 if (!mRunning) {
4086 mStarts++;
4087 mRunningSince = getBatteryUptimeLocked();
4088 mRunning = true;
4089 }
4090 }
4091
4092 public void stopRunningLocked() {
4093 if (mRunning) {
4094 long time = getBatteryUptimeLocked() - mRunningSince;
4095 if (time > 0) {
4096 mStartTime += time;
4097 } else {
4098 mStarts--;
4099 }
4100 mRunning = false;
4101 }
4102 }
4103
4104 public BatteryStatsImpl getBatteryStats() {
4105 return BatteryStatsImpl.this;
4106 }
4107
4108 @Override
4109 public int getLaunches(int which) {
4110 int val;
4111
4112 if (which == STATS_LAST) {
4113 val = mLastLaunches;
4114 } else {
4115 val = mLaunches;
4116 if (which == STATS_CURRENT) {
4117 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004118 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004119 val -= mUnpluggedLaunches;
4120 }
4121 }
4122
4123 return val;
4124 }
4125
4126 @Override
4127 public long getStartTime(long now, int which) {
4128 long val;
4129 if (which == STATS_LAST) {
4130 val = mLastStartTime;
4131 } else {
4132 val = getStartTimeToNowLocked(now);
4133 if (which == STATS_CURRENT) {
4134 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004135 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004136 val -= mUnpluggedStartTime;
4137 }
4138 }
4139
4140 return val;
4141 }
4142
4143 @Override
4144 public int getStarts(int which) {
4145 int val;
4146 if (which == STATS_LAST) {
4147 val = mLastStarts;
4148 } else {
4149 val = mStarts;
4150 if (which == STATS_CURRENT) {
4151 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004152 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004153 val -= mUnpluggedStarts;
4154 }
4155 }
4156
4157 return val;
4158 }
4159 }
4160
4161 public BatteryStatsImpl getBatteryStats() {
4162 return BatteryStatsImpl.this;
4163 }
4164
4165 public void incWakeupsLocked() {
4166 mWakeups++;
4167 }
4168
4169 final Serv newServiceStatsLocked() {
4170 return new Serv();
4171 }
4172 }
4173
4174 /**
4175 * Retrieve the statistics object for a particular process, creating
4176 * if needed.
4177 */
4178 public Proc getProcessStatsLocked(String name) {
4179 Proc ps = mProcessStats.get(name);
4180 if (ps == null) {
4181 ps = new Proc();
4182 mProcessStats.put(name, ps);
4183 }
4184
4185 return ps;
4186 }
4187
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004188 public SparseArray<? extends Pid> getPidStats() {
4189 return mPids;
4190 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004191
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004192 public Pid getPidStatsLocked(int pid) {
4193 Pid p = mPids.get(pid);
4194 if (p == null) {
4195 p = new Pid();
4196 mPids.put(pid, p);
4197 }
4198 return p;
4199 }
4200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004201 /**
4202 * Retrieve the statistics object for a particular service, creating
4203 * if needed.
4204 */
4205 public Pkg getPackageStatsLocked(String name) {
4206 Pkg ps = mPackageStats.get(name);
4207 if (ps == null) {
4208 ps = new Pkg();
4209 mPackageStats.put(name, ps);
4210 }
4211
4212 return ps;
4213 }
4214
4215 /**
4216 * Retrieve the statistics object for a particular service, creating
4217 * if needed.
4218 */
4219 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
4220 Pkg ps = getPackageStatsLocked(pkg);
4221 Pkg.Serv ss = ps.mServiceStats.get(serv);
4222 if (ss == null) {
4223 ss = ps.newServiceStatsLocked();
4224 ps.mServiceStats.put(serv, ss);
4225 }
4226
4227 return ss;
4228 }
4229
Evan Millarc64edde2009-04-18 12:26:32 -07004230 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004231 Wakelock wl = mWakelockStats.get(name);
4232 if (wl == null) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07004233 final int N = mWakelockStats.size();
Dianne Hackbornaf17baa2013-05-09 15:27:47 -07004234 if (N > MAX_WAKELOCKS_PER_UID) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004235 name = BATCHED_WAKELOCK_NAME;
4236 wl = mWakelockStats.get(name);
4237 }
4238 if (wl == null) {
4239 wl = new Wakelock();
4240 mWakelockStats.put(name, wl);
4241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 }
Evan Millarc64edde2009-04-18 12:26:32 -07004243 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004244 switch (type) {
4245 case WAKE_TYPE_PARTIAL:
4246 t = wl.mTimerPartial;
4247 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004248 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
4249 mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 wl.mTimerPartial = t;
4251 }
4252 return t;
4253 case WAKE_TYPE_FULL:
4254 t = wl.mTimerFull;
4255 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004256 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
4257 mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 wl.mTimerFull = t;
4259 }
4260 return t;
4261 case WAKE_TYPE_WINDOW:
4262 t = wl.mTimerWindow;
4263 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004264 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
4265 mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004266 wl.mTimerWindow = t;
4267 }
4268 return t;
4269 default:
4270 throw new IllegalArgumentException("type=" + type);
4271 }
4272 }
4273
Evan Millarc64edde2009-04-18 12:26:32 -07004274 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004275 Sensor se = mSensorStats.get(sensor);
4276 if (se == null) {
4277 if (!create) {
4278 return null;
4279 }
4280 se = new Sensor(sensor);
4281 mSensorStats.put(sensor, se);
4282 }
Evan Millarc64edde2009-04-18 12:26:32 -07004283 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004284 if (t != null) {
4285 return t;
4286 }
Evan Millarc64edde2009-04-18 12:26:32 -07004287 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004288 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07004289 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004290 mSensorTimers.put(sensor, timers);
4291 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004292 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 se.mTimer = t;
4294 return t;
4295 }
4296
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004297 public void noteStartWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07004298 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 if (t != null) {
4300 t.startRunningLocked(BatteryStatsImpl.this);
4301 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07004302 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004303 Pid p = getPidStatsLocked(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07004304 if (p.mWakeStart == 0) {
4305 p.mWakeStart = SystemClock.elapsedRealtime();
4306 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004307 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 }
4309
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004310 public void noteStopWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07004311 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 if (t != null) {
4313 t.stopRunningLocked(BatteryStatsImpl.this);
4314 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07004315 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004316 Pid p = mPids.get(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07004317 if (p != null && p.mWakeStart != 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004318 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
4319 p.mWakeStart = 0;
4320 }
4321 }
4322 }
4323
4324 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
4325 Proc p = getProcessStatsLocked(proc);
4326 if (p != null) {
4327 p.addExcessiveWake(overTime, usedTime);
4328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004329 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004330
Dianne Hackborn287952c2010-09-22 22:34:31 -07004331 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
4332 Proc p = getProcessStatsLocked(proc);
4333 if (p != null) {
4334 p.addExcessiveCpu(overTime, usedTime);
4335 }
4336 }
4337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004338 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07004339 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004340 if (t != null) {
4341 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004343 }
4344
4345 public void noteStopSensor(int sensor) {
4346 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07004347 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004348 if (t != null) {
4349 t.stopRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004351 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004354 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355 if (t != null) {
4356 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004357 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004358 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004361 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362 if (t != null) {
4363 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004365 }
4366
4367 public BatteryStatsImpl getBatteryStats() {
4368 return BatteryStatsImpl.this;
4369 }
4370 }
4371
4372 public BatteryStatsImpl(String filename) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004373 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004374 mHandler = new MyHandler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004375 mStartCount++;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004376 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004377 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004378 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004379 }
4380 mInputEventCounter = new Counter(mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004381 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
Wink Saville52840902011-02-18 12:40:47 -08004382 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004383 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004384 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004385 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004386 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004387 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004388 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004389 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
4390 mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
4391 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004392 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004393 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004394 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
4395 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
4396 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004398 initTimes();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 mTrackBatteryPastUptime = 0;
4400 mTrackBatteryPastRealtime = 0;
4401 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4402 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4403 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4404 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07004405 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004406 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07004407 mDischargeCurrentLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004408 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004409 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 }
4411
4412 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004413 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004414 mHandler = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004415 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416 readFromParcel(p);
4417 }
4418
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004419 public void setCallback(BatteryCallback cb) {
4420 mCallback = cb;
4421 }
4422
Amith Yamasanie43530a2009-08-21 13:11:37 -07004423 public void setNumSpeedSteps(int steps) {
4424 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
4425 }
4426
Amith Yamasanif37447b2009-10-08 18:28:01 -07004427 public void setRadioScanningTimeout(long timeout) {
4428 if (mPhoneSignalScanningTimer != null) {
4429 mPhoneSignalScanningTimer.setTimeout(timeout);
4430 }
4431 }
4432
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004433 @Override
4434 public boolean startIteratingOldHistoryLocked() {
4435 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4436 + " pos=" + mHistoryBuffer.dataPosition());
4437 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004438 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004439 mReadOverflow = false;
4440 mIteratingHistory = true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004441 return (mHistoryIterator = mHistory) != null;
4442 }
4443
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004444 @Override
4445 public boolean getNextOldHistoryLocked(HistoryItem out) {
4446 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
4447 if (!end) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004448 mHistoryReadTmp.readDelta(mHistoryBuffer);
4449 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004450 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004451 HistoryItem cur = mHistoryIterator;
4452 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004453 if (!mReadOverflow && !end) {
4454 Slog.w(TAG, "Old history ends before new history!");
4455 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004456 return false;
4457 }
4458 out.setTo(cur);
4459 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004460 if (!mReadOverflow) {
4461 if (end) {
4462 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004463 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004464 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
Dianne Hackborn8c841092013-06-24 13:46:13 -07004465 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004466 pw.println("Histories differ!");
4467 pw.println("Old history:");
4468 (new HistoryPrinter()).printNextItem(pw, out, now);
4469 pw.println("New history:");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004470 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now);
Dianne Hackborn8c841092013-06-24 13:46:13 -07004471 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004472 }
4473 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004474 return true;
4475 }
4476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004477 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004478 public void finishIteratingOldHistoryLocked() {
4479 mIteratingHistory = false;
4480 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
4481 }
4482
4483 @Override
4484 public boolean startIteratingHistoryLocked() {
4485 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4486 + " pos=" + mHistoryBuffer.dataPosition());
4487 mHistoryBuffer.setDataPosition(0);
4488 mReadOverflow = false;
4489 mIteratingHistory = true;
4490 return mHistoryBuffer.dataSize() > 0;
4491 }
4492
4493 @Override
4494 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004495 final int pos = mHistoryBuffer.dataPosition();
4496 if (pos == 0) {
4497 out.clear();
4498 }
4499 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004500 if (end) {
4501 return false;
4502 }
4503
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004504 out.readDelta(mHistoryBuffer);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004505 return true;
4506 }
4507
4508 @Override
4509 public void finishIteratingHistoryLocked() {
4510 mIteratingHistory = false;
4511 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004512 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004513
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004514 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004515 public long getHistoryBaseTime() {
4516 return mHistoryBaseTime;
4517 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004518
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004519 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 public int getStartCount() {
4521 return mStartCount;
4522 }
4523
4524 public boolean isOnBattery() {
4525 return mOnBattery;
4526 }
4527
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004528 public boolean isScreenOn() {
4529 return mScreenOn;
4530 }
4531
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004532 void initTimes() {
4533 mBatteryRealtime = mTrackBatteryPastUptime = 0;
4534 mBatteryUptime = mTrackBatteryPastRealtime = 0;
4535 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4536 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4537 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4538 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
4539 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004540
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004541 void initDischarge() {
4542 mLowDischargeAmountSinceCharge = 0;
4543 mHighDischargeAmountSinceCharge = 0;
4544 mDischargeAmountScreenOn = 0;
4545 mDischargeAmountScreenOnSinceCharge = 0;
4546 mDischargeAmountScreenOff = 0;
4547 mDischargeAmountScreenOffSinceCharge = 0;
4548 }
4549
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004550 public void resetAllStatsLocked() {
4551 mStartCount = 0;
4552 initTimes();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004553 mScreenOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004554 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004555 mScreenBrightnessTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004556 }
4557 mInputEventCounter.reset(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004558 mPhoneOnTimer.reset(this, false);
4559 mAudioOnTimer.reset(this, false);
4560 mVideoOnTimer.reset(this, false);
Wink Saville52840902011-02-18 12:40:47 -08004561 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004562 mPhoneSignalStrengthsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004563 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004564 mPhoneSignalScanningTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004565 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004566 mPhoneDataConnectionsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004567 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004568 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
4569 mNetworkActivityCounters[i].reset(false);
4570 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004571 mWifiOnTimer.reset(this, false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004572 mGlobalWifiRunningTimer.reset(this, false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004573 mBluetoothOnTimer.reset(this, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004574
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004575 for (int i=0; i<mUidStats.size(); i++) {
4576 if (mUidStats.valueAt(i).reset()) {
4577 mUidStats.remove(mUidStats.keyAt(i));
4578 i--;
4579 }
4580 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004581
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004582 if (mKernelWakelockStats.size() > 0) {
4583 for (SamplingTimer timer : mKernelWakelockStats.values()) {
4584 mUnpluggables.remove(timer);
4585 }
4586 mKernelWakelockStats.clear();
4587 }
4588
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004589 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004590
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004591 clearHistoryLocked();
4592 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004593
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004594 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004595 if (oldScreenOn) {
4596 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
4597 if (diff > 0) {
4598 mDischargeAmountScreenOn += diff;
4599 mDischargeAmountScreenOnSinceCharge += diff;
4600 }
4601 } else {
4602 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
4603 if (diff > 0) {
4604 mDischargeAmountScreenOff += diff;
4605 mDischargeAmountScreenOffSinceCharge += diff;
4606 }
4607 }
4608 if (newScreenOn) {
4609 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
4610 mDischargeScreenOffUnplugLevel = 0;
4611 } else {
4612 mDischargeScreenOnUnplugLevel = 0;
4613 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
4614 }
4615 }
4616
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004617 void setOnBattery(boolean onBattery, int oldStatus, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618 synchronized(this) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004619 setOnBatteryLocked(onBattery, oldStatus, level);
4620 }
4621 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004622
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004623 void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
4624 boolean doWrite = false;
4625 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
4626 m.arg1 = onBattery ? 1 : 0;
4627 mHandler.sendMessage(m);
4628 mOnBattery = mOnBatteryInternal = onBattery;
4629
4630 long uptime = SystemClock.uptimeMillis() * 1000;
4631 long mSecRealtime = SystemClock.elapsedRealtime();
4632 long realtime = mSecRealtime * 1000;
4633 if (onBattery) {
4634 // We will reset our status if we are unplugging after the
4635 // battery was last full, or the level is at 100, or
4636 // we have gone through a significant charge (from a very low
4637 // level to a now very high level).
4638 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
4639 || level >= 90
4640 || (mDischargeCurrentLevel < 20 && level >= 80)) {
4641 doWrite = true;
4642 resetAllStatsLocked();
4643 mDischargeStartLevel = level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004644 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004645 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004646 updateNetworkActivityLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004647 mHistoryCur.batteryLevel = (byte)level;
4648 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4649 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
4650 + Integer.toHexString(mHistoryCur.states));
4651 addHistoryRecordLocked(mSecRealtime);
4652 mTrackBatteryUptimeStart = uptime;
4653 mTrackBatteryRealtimeStart = realtime;
4654 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
4655 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
4656 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
4657 if (mScreenOn) {
4658 mDischargeScreenOnUnplugLevel = level;
4659 mDischargeScreenOffUnplugLevel = 0;
4660 } else {
4661 mDischargeScreenOnUnplugLevel = 0;
4662 mDischargeScreenOffUnplugLevel = level;
4663 }
4664 mDischargeAmountScreenOn = 0;
4665 mDischargeAmountScreenOff = 0;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004666 doUnplugLocked(realtime, mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004667 } else {
4668 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004669 updateNetworkActivityLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004670 mHistoryCur.batteryLevel = (byte)level;
4671 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4672 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
4673 + Integer.toHexString(mHistoryCur.states));
4674 addHistoryRecordLocked(mSecRealtime);
4675 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
4676 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
4677 mDischargeCurrentLevel = level;
4678 if (level < mDischargeUnplugLevel) {
4679 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
4680 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
4681 }
4682 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004683 doPlugLocked(realtime, getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004684 }
4685 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
4686 if (mFile != null) {
4687 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688 }
4689 }
4690 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004691
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004692 // This should probably be exposed in the API, though it's not critical
4693 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004694
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004695 public void setBatteryState(int status, int health, int plugType, int level,
4696 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004697 synchronized(this) {
4698 boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
4699 int oldStatus = mHistoryCur.batteryStatus;
4700 if (!mHaveBatteryLevel) {
4701 mHaveBatteryLevel = true;
4702 // We start out assuming that the device is plugged in (not
4703 // on battery). If our first report is now that we are indeed
4704 // plugged in, then twiddle our state to correctly reflect that
4705 // since we won't be going through the full setOnBattery().
4706 if (onBattery == mOnBattery) {
4707 if (onBattery) {
4708 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4709 } else {
4710 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4711 }
4712 }
4713 oldStatus = status;
4714 }
4715 if (onBattery) {
4716 mDischargeCurrentLevel = level;
4717 mRecordingHistory = true;
4718 }
4719 if (onBattery != mOnBattery) {
4720 mHistoryCur.batteryLevel = (byte)level;
4721 mHistoryCur.batteryStatus = (byte)status;
4722 mHistoryCur.batteryHealth = (byte)health;
4723 mHistoryCur.batteryPlugType = (byte)plugType;
4724 mHistoryCur.batteryTemperature = (char)temp;
4725 mHistoryCur.batteryVoltage = (char)volt;
4726 setOnBatteryLocked(onBattery, oldStatus, level);
4727 } else {
4728 boolean changed = false;
4729 if (mHistoryCur.batteryLevel != level) {
4730 mHistoryCur.batteryLevel = (byte)level;
4731 changed = true;
4732 }
4733 if (mHistoryCur.batteryStatus != status) {
4734 mHistoryCur.batteryStatus = (byte)status;
4735 changed = true;
4736 }
4737 if (mHistoryCur.batteryHealth != health) {
4738 mHistoryCur.batteryHealth = (byte)health;
4739 changed = true;
4740 }
4741 if (mHistoryCur.batteryPlugType != plugType) {
4742 mHistoryCur.batteryPlugType = (byte)plugType;
4743 changed = true;
4744 }
4745 if (temp >= (mHistoryCur.batteryTemperature+10)
4746 || temp <= (mHistoryCur.batteryTemperature-10)) {
4747 mHistoryCur.batteryTemperature = (char)temp;
4748 changed = true;
4749 }
4750 if (volt > (mHistoryCur.batteryVoltage+20)
4751 || volt < (mHistoryCur.batteryVoltage-20)) {
4752 mHistoryCur.batteryVoltage = (char)volt;
4753 changed = true;
4754 }
4755 if (changed) {
4756 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004757 }
4758 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004759 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
4760 // We don't record history while we are plugged in and fully charged.
4761 // The next time we are unplugged, history will be cleared.
4762 mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004763 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004764 }
Evan Millar633a1742009-04-02 16:36:33 -07004765 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004766
Evan Millarc64edde2009-04-18 12:26:32 -07004767 public void updateKernelWakelocksLocked() {
4768 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004769
Marco Nelissend8593312009-04-30 14:45:06 -07004770 if (m == null) {
4771 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004772 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07004773 return;
4774 }
4775
Evan Millarc64edde2009-04-18 12:26:32 -07004776 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
4777 String name = ent.getKey();
4778 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004779
Evan Millarc64edde2009-04-18 12:26:32 -07004780 SamplingTimer kwlt = mKernelWakelockStats.get(name);
4781 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004782 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07004783 true /* track reported values */);
4784 mKernelWakelockStats.put(name, kwlt);
4785 }
4786 kwlt.updateCurrentReportedCount(kws.mCount);
4787 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
4788 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
4789 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004790
Evan Millarc64edde2009-04-18 12:26:32 -07004791 if (m.size() != mKernelWakelockStats.size()) {
4792 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
4793 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4794 SamplingTimer st = ent.getValue();
4795 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
4796 st.setStale();
4797 }
4798 }
4799 }
4800 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004801
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004802 private void updateNetworkActivityLocked() {
4803 if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
4804
4805 final NetworkStats snapshot;
4806 try {
4807 snapshot = mNetworkStatsFactory.readNetworkStatsDetail();
4808 } catch (IOException e) {
4809 Log.wtf(TAG, "Failed to read network stats", e);
4810 return;
4811 }
4812
4813 if (mLastSnapshot == null) {
4814 mLastSnapshot = snapshot;
4815 return;
4816 }
4817
4818 final NetworkStats delta = snapshot.subtract(mLastSnapshot);
4819 mLastSnapshot = snapshot;
4820
4821 NetworkStats.Entry entry = null;
4822 final int size = delta.size();
4823 for (int i = 0; i < size; i++) {
4824 entry = delta.getValues(i, entry);
4825
4826 if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
4827 if (entry.tag != NetworkStats.TAG_NONE) continue;
4828
4829 final Uid u = getUidStatsLocked(entry.uid);
4830
4831 if (mMobileIfaces.contains(entry.iface)) {
4832 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_BYTES, entry.rxBytes);
4833 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_BYTES, entry.txBytes);
4834
4835 mNetworkActivityCounters[NETWORK_MOBILE_RX_BYTES].addCountLocked(entry.rxBytes);
4836 mNetworkActivityCounters[NETWORK_MOBILE_TX_BYTES].addCountLocked(entry.txBytes);
4837
4838 } else if (mWifiIfaces.contains(entry.iface)) {
4839 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_BYTES, entry.rxBytes);
4840 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_BYTES, entry.txBytes);
4841
4842 mNetworkActivityCounters[NETWORK_WIFI_RX_BYTES].addCountLocked(entry.rxBytes);
4843 mNetworkActivityCounters[NETWORK_WIFI_TX_BYTES].addCountLocked(entry.txBytes);
4844 }
4845 }
4846 }
4847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 public long getAwakeTimeBattery() {
4849 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
4850 }
4851
4852 public long getAwakeTimePlugged() {
4853 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
4854 }
4855
4856 @Override
4857 public long computeUptime(long curTime, int which) {
4858 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004859 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004860 case STATS_LAST: return mLastUptime;
4861 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004862 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004863 }
4864 return 0;
4865 }
4866
4867 @Override
4868 public long computeRealtime(long curTime, int which) {
4869 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004870 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004871 case STATS_LAST: return mLastRealtime;
4872 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004873 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874 }
4875 return 0;
4876 }
4877
4878 @Override
4879 public long computeBatteryUptime(long curTime, int which) {
4880 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004881 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004882 return mBatteryUptime + getBatteryUptime(curTime);
4883 case STATS_LAST:
4884 return mBatteryLastUptime;
4885 case STATS_CURRENT:
4886 return getBatteryUptime(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004887 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004888 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
4889 }
4890 return 0;
4891 }
4892
4893 @Override
4894 public long computeBatteryRealtime(long curTime, int which) {
4895 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004896 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004897 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
4898 case STATS_LAST:
4899 return mBatteryLastRealtime;
4900 case STATS_CURRENT:
4901 return getBatteryRealtimeLocked(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004902 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004903 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
4904 }
4905 return 0;
4906 }
4907
4908 long getBatteryUptimeLocked(long curTime) {
4909 long time = mTrackBatteryPastUptime;
4910 if (mOnBatteryInternal) {
4911 time += curTime - mTrackBatteryUptimeStart;
4912 }
4913 return time;
4914 }
4915
4916 long getBatteryUptimeLocked() {
4917 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
4918 }
4919
4920 @Override
4921 public long getBatteryUptime(long curTime) {
4922 return getBatteryUptimeLocked(curTime);
4923 }
4924
4925 long getBatteryRealtimeLocked(long curTime) {
4926 long time = mTrackBatteryPastRealtime;
4927 if (mOnBatteryInternal) {
4928 time += curTime - mTrackBatteryRealtimeStart;
4929 }
4930 return time;
4931 }
4932
4933 @Override
4934 public long getBatteryRealtime(long curTime) {
4935 return getBatteryRealtimeLocked(curTime);
4936 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004937
The Android Open Source Project10592532009-03-18 17:39:46 -07004938 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004939 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004940 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004941 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004942 }
4943 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004944
Evan Millar633a1742009-04-02 16:36:33 -07004945 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004946 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004947 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004948
The Android Open Source Project10592532009-03-18 17:39:46 -07004949 @Override
Evan Millar633a1742009-04-02 16:36:33 -07004950 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004951 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07004952 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07004953 }
4954 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004955
Evan Millar633a1742009-04-02 16:36:33 -07004956 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004957 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07004958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004959
Amith Yamasanie43530a2009-08-21 13:11:37 -07004960 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004961 public int getLowDischargeAmountSinceCharge() {
4962 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004963 int val = mLowDischargeAmountSinceCharge;
4964 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4965 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
4966 }
4967 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004968 }
4969 }
4970
4971 @Override
4972 public int getHighDischargeAmountSinceCharge() {
4973 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004974 int val = mHighDischargeAmountSinceCharge;
4975 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
4976 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
4977 }
4978 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004979 }
4980 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004981
4982 public int getDischargeAmountScreenOn() {
4983 synchronized(this) {
4984 int val = mDischargeAmountScreenOn;
4985 if (mOnBattery && mScreenOn
4986 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4987 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4988 }
4989 return val;
4990 }
4991 }
4992
4993 public int getDischargeAmountScreenOnSinceCharge() {
4994 synchronized(this) {
4995 int val = mDischargeAmountScreenOnSinceCharge;
4996 if (mOnBattery && mScreenOn
4997 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
4998 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
4999 }
5000 return val;
5001 }
5002 }
5003
5004 public int getDischargeAmountScreenOff() {
5005 synchronized(this) {
5006 int val = mDischargeAmountScreenOff;
5007 if (mOnBattery && !mScreenOn
5008 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
5009 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
5010 }
5011 return val;
5012 }
5013 }
5014
5015 public int getDischargeAmountScreenOffSinceCharge() {
5016 synchronized(this) {
5017 int val = mDischargeAmountScreenOffSinceCharge;
5018 if (mOnBattery && !mScreenOn
5019 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
5020 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
5021 }
5022 return val;
5023 }
5024 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005025
5026 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07005027 public int getCpuSpeedSteps() {
5028 return sNumSpeedSteps;
5029 }
5030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005031 /**
5032 * Retrieve the statistics object for a particular uid, creating if needed.
5033 */
5034 public Uid getUidStatsLocked(int uid) {
5035 Uid u = mUidStats.get(uid);
5036 if (u == null) {
5037 u = new Uid(uid);
5038 mUidStats.put(uid, u);
5039 }
5040 return u;
5041 }
5042
5043 /**
5044 * Remove the statistics object for a particular uid.
5045 */
5046 public void removeUidStatsLocked(int uid) {
5047 mUidStats.remove(uid);
5048 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07005049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005050 /**
5051 * Retrieve the statistics object for a particular process, creating
5052 * if needed.
5053 */
5054 public Uid.Proc getProcessStatsLocked(int uid, String name) {
5055 Uid u = getUidStatsLocked(uid);
5056 return u.getProcessStatsLocked(name);
5057 }
5058
5059 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07005060 * Retrieve the statistics object for a particular process, given
5061 * the name of the process.
5062 * @param name process name
5063 * @return the statistics object for the process
5064 */
Amith Yamasani819f9282009-06-24 23:18:15 -07005065 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07005066 int uid;
5067 if (mUidCache.containsKey(name)) {
5068 uid = mUidCache.get(name);
5069 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07005070 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07005071 mUidCache.put(name, uid);
5072 }
5073 Uid u = getUidStatsLocked(uid);
5074 return u.getProcessStatsLocked(name);
5075 }
5076
5077 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005078 * Retrieve the statistics object for a particular process, creating
5079 * if needed.
5080 */
5081 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
5082 Uid u = getUidStatsLocked(uid);
5083 return u.getPackageStatsLocked(pkg);
5084 }
5085
5086 /**
5087 * Retrieve the statistics object for a particular service, creating
5088 * if needed.
5089 */
5090 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
5091 Uid u = getUidStatsLocked(uid);
5092 return u.getServiceStatsLocked(pkg, name);
5093 }
5094
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005095 /**
5096 * Massage data to distribute any reasonable work down to more specific
5097 * owners. Must only be called on a dead BatteryStats object!
5098 */
5099 public void distributeWorkLocked(int which) {
5100 // Aggregate all CPU time associated with WIFI.
5101 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
5102 if (wifiUid != null) {
5103 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
5104 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
5105 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
5106 for (int i=0; i<mUidStats.size(); i++) {
5107 Uid uid = mUidStats.valueAt(i);
5108 if (uid.mUid != Process.WIFI_UID) {
5109 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
5110 if (uidRunningTime > 0) {
5111 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
5112 long time = proc.getUserTime(which);
5113 time = (time*uidRunningTime)/totalRunningTime;
5114 uidProc.mUserTime += time;
5115 proc.mUserTime -= time;
5116 time = proc.getSystemTime(which);
5117 time = (time*uidRunningTime)/totalRunningTime;
5118 uidProc.mSystemTime += time;
5119 proc.mSystemTime -= time;
5120 time = proc.getForegroundTime(which);
5121 time = (time*uidRunningTime)/totalRunningTime;
5122 uidProc.mForegroundTime += time;
5123 proc.mForegroundTime -= time;
5124 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
5125 SamplingCounter sc = proc.mSpeedBins[sb];
5126 if (sc != null) {
5127 time = sc.getCountLocked(which);
5128 time = (time*uidRunningTime)/totalRunningTime;
5129 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
5130 if (uidSc == null) {
5131 uidSc = new SamplingCounter(mUnpluggables);
5132 uidProc.mSpeedBins[sb] = uidSc;
5133 }
5134 uidSc.mCount.addAndGet((int)time);
5135 sc.mCount.addAndGet((int)-time);
5136 }
5137 }
5138 totalRunningTime -= uidRunningTime;
5139 }
5140 }
5141 }
5142 }
5143 }
5144 }
5145
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005146 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005147 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005148 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005149 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005150
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005151 Parcel mPendingWrite = null;
5152 final ReentrantLock mWriteLock = new ReentrantLock();
5153
5154 public void writeAsyncLocked() {
5155 writeLocked(false);
5156 }
5157
5158 public void writeSyncLocked() {
5159 writeLocked(true);
5160 }
5161
5162 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005163 if (mFile == null) {
5164 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 return;
5166 }
5167
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005168 if (mShuttingDown) {
5169 return;
5170 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005171
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005172 Parcel out = Parcel.obtain();
5173 writeSummaryToParcel(out);
5174 mLastWriteTime = SystemClock.elapsedRealtime();
5175
5176 if (mPendingWrite != null) {
5177 mPendingWrite.recycle();
5178 }
5179 mPendingWrite = out;
5180
5181 if (sync) {
5182 commitPendingDataToDisk();
5183 } else {
5184 Thread thr = new Thread("BatteryStats-Write") {
5185 @Override
5186 public void run() {
5187 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5188 commitPendingDataToDisk();
5189 }
5190 };
5191 thr.start();
5192 }
5193 }
5194
5195 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07005196 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005197 synchronized (this) {
5198 next = mPendingWrite;
5199 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07005200 if (next == null) {
5201 return;
5202 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005203
5204 mWriteLock.lock();
5205 }
5206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005208 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005209 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005210 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07005211 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005212 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005213 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005214 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005215 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005216 mFile.rollback();
5217 } finally {
5218 next.recycle();
5219 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07005220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005221 }
5222
5223 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
5224 int pos = 0;
5225 int avail = stream.available();
5226 byte[] data = new byte[avail];
5227 while (true) {
5228 int amt = stream.read(data, pos, data.length-pos);
5229 //Log.i("foo", "Read " + amt + " bytes at " + pos
5230 // + " of avail " + data.length);
5231 if (amt <= 0) {
5232 //Log.i("foo", "**** FINISHED READING: pos=" + pos
5233 // + " len=" + data.length);
5234 return data;
5235 }
5236 pos += amt;
5237 avail = stream.available();
5238 if (avail > data.length-pos) {
5239 byte[] newData = new byte[pos+avail];
5240 System.arraycopy(data, 0, newData, 0, pos);
5241 data = newData;
5242 }
5243 }
5244 }
5245
5246 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005247 if (mFile == null) {
5248 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 return;
5250 }
5251
5252 mUidStats.clear();
5253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005254 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005255 File file = mFile.chooseForRead();
5256 if (!file.exists()) {
5257 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005258 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005259 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005260
5261 byte[] raw = readFully(stream);
5262 Parcel in = Parcel.obtain();
5263 in.unmarshall(raw, 0, raw.length);
5264 in.setDataPosition(0);
5265 stream.close();
5266
5267 readSummaryFromParcel(in);
5268 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005269 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005270 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005271
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005272 long now = SystemClock.elapsedRealtime();
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005273 if (USE_OLD_HISTORY) {
5274 addHistoryRecordLocked(now, HistoryItem.CMD_START);
5275 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005276 addHistoryBufferLocked(now, HistoryItem.CMD_START);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005277 }
5278
5279 public int describeContents() {
5280 return 0;
5281 }
5282
Dianne Hackbornae384452011-06-28 12:33:48 -07005283 void readHistory(Parcel in, boolean andOldHistory) {
5284 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005285
5286 mHistoryBuffer.setDataSize(0);
5287 mHistoryBuffer.setDataPosition(0);
5288
5289 int bufSize = in.readInt();
5290 int curPos = in.dataPosition();
5291 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
5292 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
5293 } else if ((bufSize&~3) != bufSize) {
5294 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
5295 } else {
5296 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
5297 + " bytes at " + curPos);
5298 mHistoryBuffer.appendFrom(in, curPos, bufSize);
5299 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005300 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005301
Dianne Hackbornae384452011-06-28 12:33:48 -07005302 if (andOldHistory) {
5303 readOldHistory(in);
5304 }
5305
5306 if (DEBUG_HISTORY) {
5307 StringBuilder sb = new StringBuilder(128);
5308 sb.append("****************** OLD mHistoryBaseTime: ");
5309 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5310 Slog.i(TAG, sb.toString());
5311 }
5312 mHistoryBaseTime = historyBaseTime;
5313 if (DEBUG_HISTORY) {
5314 StringBuilder sb = new StringBuilder(128);
5315 sb.append("****************** NEW mHistoryBaseTime: ");
5316 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5317 Slog.i(TAG, sb.toString());
5318 }
5319
5320 // We are just arbitrarily going to insert 1 minute from the sample of
5321 // the last run until samples in this run.
5322 if (mHistoryBaseTime > 0) {
5323 long oldnow = SystemClock.elapsedRealtime();
5324 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000;
5325 if (DEBUG_HISTORY) {
5326 StringBuilder sb = new StringBuilder(128);
5327 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
5328 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5329 Slog.i(TAG, sb.toString());
5330 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07005331 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005332 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005333
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005334 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005335 if (!USE_OLD_HISTORY) {
5336 return;
5337 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005338 mHistory = mHistoryEnd = mHistoryCache = null;
5339 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07005340 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005341 HistoryItem rec = new HistoryItem(time, in);
5342 addHistoryRecordLocked(rec);
5343 }
5344 }
5345
Dianne Hackbornae384452011-06-28 12:33:48 -07005346 void writeHistory(Parcel out, boolean andOldHistory) {
5347 if (DEBUG_HISTORY) {
5348 StringBuilder sb = new StringBuilder(128);
5349 sb.append("****************** WRITING mHistoryBaseTime: ");
5350 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5351 sb.append(" mLastHistoryTime: ");
5352 TimeUtils.formatDuration(mLastHistoryTime, sb);
5353 Slog.i(TAG, sb.toString());
5354 }
5355 out.writeLong(mHistoryBaseTime + mLastHistoryTime);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005356 out.writeInt(mHistoryBuffer.dataSize());
5357 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
5358 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
5359 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07005360
5361 if (andOldHistory) {
5362 writeOldHistory(out);
5363 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005364 }
5365
5366 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005367 if (!USE_OLD_HISTORY) {
5368 return;
5369 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005370 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005371 while (rec != null) {
5372 if (rec.time >= 0) rec.writeToParcel(out, 0);
5373 rec = rec.next;
5374 }
5375 out.writeLong(-1);
5376 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005378 private void readSummaryFromParcel(Parcel in) {
5379 final int version = in.readInt();
5380 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005381 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005382 + ", expected " + VERSION + "; erasing old stats");
5383 return;
5384 }
5385
Dianne Hackbornae384452011-06-28 12:33:48 -07005386 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005388 mStartCount = in.readInt();
5389 mBatteryUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005390 mBatteryRealtime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005391 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005392 mRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005393 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005394 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005395 mLowDischargeAmountSinceCharge = in.readInt();
5396 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005397 mDischargeAmountScreenOnSinceCharge = in.readInt();
5398 mDischargeAmountScreenOffSinceCharge = in.readInt();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005400 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005402 mScreenOn = false;
5403 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005404 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5405 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
5406 }
5407 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005408 mPhoneOn = false;
5409 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08005410 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005411 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
5412 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005413 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005414 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5415 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
5416 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005417 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5418 mNetworkActivityCounters[i].readSummaryFromParcelLocked(in);
5419 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005420 mWifiOn = false;
5421 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005422 mGlobalWifiRunning = false;
5423 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005424 mBluetoothOn = false;
5425 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005426
Evan Millarc64edde2009-04-18 12:26:32 -07005427 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005428 if (NKW > 10000) {
5429 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
5430 return;
5431 }
Evan Millarc64edde2009-04-18 12:26:32 -07005432 for (int ikw = 0; ikw < NKW; ikw++) {
5433 if (in.readInt() != 0) {
5434 String kwltName = in.readString();
5435 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
5436 }
5437 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005438
5439 sNumSpeedSteps = in.readInt();
5440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005441 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005442 if (NU > 10000) {
5443 Slog.w(TAG, "File corrupt: too many uids " + NU);
5444 return;
5445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 for (int iu = 0; iu < NU; iu++) {
5447 int uid = in.readInt();
5448 Uid u = new Uid(uid);
5449 mUidStats.put(uid, u);
5450
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005451 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005452 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005453 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005454 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005455 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005456 if (in.readInt() != 0) {
5457 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
5458 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005459 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005460 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005461 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005462 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005463 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005464 if (in.readInt() != 0) {
5465 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
5466 }
5467 u.mAudioTurnedOn = false;
5468 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005469 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005470 }
5471 u.mVideoTurnedOn = false;
5472 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005473 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
5474 }
5475 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005476 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
5477 }
5478 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005479 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005480 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005481
Dianne Hackborn617f8772009-03-31 15:04:46 -07005482 if (in.readInt() != 0) {
5483 if (u.mUserActivityCounters == null) {
5484 u.initUserActivityLocked();
5485 }
5486 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5487 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
5488 }
5489 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005490
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005491 if (in.readInt() != 0) {
5492 if (u.mNetworkActivityCounters == null) {
5493 u.initNetworkActivityLocked();
5494 }
5495 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5496 u.mNetworkActivityCounters[i].readSummaryFromParcelLocked(in);
5497 }
5498 }
5499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005500 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005501 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005502 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
5503 return;
5504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005505 for (int iw = 0; iw < NW; iw++) {
5506 String wlName = in.readString();
5507 if (in.readInt() != 0) {
5508 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
5509 }
5510 if (in.readInt() != 0) {
5511 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
5512 }
5513 if (in.readInt() != 0) {
5514 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
5515 }
5516 }
5517
5518 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005519 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005520 Slog.w(TAG, "File corrupt: too many sensors " + NP);
5521 return;
5522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005523 for (int is = 0; is < NP; is++) {
5524 int seNumber = in.readInt();
5525 if (in.readInt() != 0) {
5526 u.getSensorTimerLocked(seNumber, true)
5527 .readSummaryFromParcelLocked(in);
5528 }
5529 }
5530
5531 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005532 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005533 Slog.w(TAG, "File corrupt: too many processes " + NP);
5534 return;
5535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005536 for (int ip = 0; ip < NP; ip++) {
5537 String procName = in.readString();
5538 Uid.Proc p = u.getProcessStatsLocked(procName);
5539 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005540 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005541 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005542 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005543 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005544 if (NSB > 100) {
5545 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
5546 return;
5547 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005548 p.mSpeedBins = new SamplingCounter[NSB];
5549 for (int i=0; i<NSB; i++) {
5550 if (in.readInt() != 0) {
5551 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables);
5552 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
5553 }
5554 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005555 if (!p.readExcessivePowerFromParcelLocked(in)) {
5556 return;
5557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005558 }
5559
5560 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005561 if (NP > 10000) {
5562 Slog.w(TAG, "File corrupt: too many packages " + NP);
5563 return;
5564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005565 for (int ip = 0; ip < NP; ip++) {
5566 String pkgName = in.readString();
5567 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
5568 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005570 if (NS > 1000) {
5571 Slog.w(TAG, "File corrupt: too many services " + NS);
5572 return;
5573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005574 for (int is = 0; is < NS; is++) {
5575 String servName = in.readString();
5576 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
5577 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005578 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005579 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005580 }
5581 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005582 }
5583 }
5584
5585 /**
5586 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
5587 * disk. This format does not allow a lossless round-trip.
5588 *
5589 * @param out the Parcel to be written to.
5590 */
5591 public void writeSummaryToParcel(Parcel out) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005592 // Need to update with current kernel wake lock counts.
5593 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005594 updateNetworkActivityLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005596 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
5597 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
5598 final long NOW = getBatteryUptimeLocked(NOW_SYS);
5599 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
5600
5601 out.writeInt(VERSION);
5602
Dianne Hackbornae384452011-06-28 12:33:48 -07005603 writeHistory(out, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005605 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005606 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005607 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005608 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005609 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005610 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005611 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08005612 out.writeInt(getLowDischargeAmountSinceCharge());
5613 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005614 out.writeInt(getDischargeAmountScreenOnSinceCharge());
5615 out.writeInt(getDischargeAmountScreenOffSinceCharge());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005616
5617 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005618 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5619 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5620 }
5621 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005622 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Wink Saville52840902011-02-18 12:40:47 -08005623 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005624 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5625 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005626 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005627 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5628 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5629 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005630 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5631 mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out);
5632 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005633 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005634 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07005635 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005636
Evan Millarc64edde2009-04-18 12:26:32 -07005637 out.writeInt(mKernelWakelockStats.size());
5638 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5639 Timer kwlt = ent.getValue();
5640 if (kwlt != null) {
5641 out.writeInt(1);
5642 out.writeString(ent.getKey());
5643 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
5644 } else {
5645 out.writeInt(0);
5646 }
5647 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005648
Amith Yamasanie43530a2009-08-21 13:11:37 -07005649 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005650 final int NU = mUidStats.size();
5651 out.writeInt(NU);
5652 for (int iu = 0; iu < NU; iu++) {
5653 out.writeInt(mUidStats.keyAt(iu));
5654 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005655
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005656 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005657 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005658 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005659 } else {
5660 out.writeInt(0);
5661 }
5662 if (u.mFullWifiLockTimer != null) {
5663 out.writeInt(1);
5664 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5665 } else {
5666 out.writeInt(0);
5667 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005668 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005669 out.writeInt(1);
Nick Pelly6ccaa542012-06-15 15:22:47 -07005670 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005671 } else {
5672 out.writeInt(0);
5673 }
5674 if (u.mWifiMulticastTimer != null) {
5675 out.writeInt(1);
5676 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5677 } else {
5678 out.writeInt(0);
5679 }
5680 if (u.mAudioTurnedOnTimer != null) {
5681 out.writeInt(1);
5682 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5683 } else {
5684 out.writeInt(0);
5685 }
5686 if (u.mVideoTurnedOnTimer != null) {
5687 out.writeInt(1);
5688 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5689 } else {
5690 out.writeInt(0);
5691 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005692 if (u.mForegroundActivityTimer != null) {
5693 out.writeInt(1);
5694 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5695 } else {
5696 out.writeInt(0);
5697 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005698 if (u.mVibratorOnTimer != null) {
5699 out.writeInt(1);
5700 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5701 } else {
5702 out.writeInt(0);
5703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005704
Dianne Hackborn617f8772009-03-31 15:04:46 -07005705 if (u.mUserActivityCounters == null) {
5706 out.writeInt(0);
5707 } else {
5708 out.writeInt(1);
5709 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5710 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
5711 }
5712 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005713
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005714 if (u.mNetworkActivityCounters == null) {
5715 out.writeInt(0);
5716 } else {
5717 out.writeInt(1);
5718 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5719 u.mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out);
5720 }
5721 }
5722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005723 int NW = u.mWakelockStats.size();
5724 out.writeInt(NW);
5725 if (NW > 0) {
5726 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
5727 : u.mWakelockStats.entrySet()) {
5728 out.writeString(ent.getKey());
5729 Uid.Wakelock wl = ent.getValue();
5730 if (wl.mTimerFull != null) {
5731 out.writeInt(1);
5732 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
5733 } else {
5734 out.writeInt(0);
5735 }
5736 if (wl.mTimerPartial != null) {
5737 out.writeInt(1);
5738 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
5739 } else {
5740 out.writeInt(0);
5741 }
5742 if (wl.mTimerWindow != null) {
5743 out.writeInt(1);
5744 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
5745 } else {
5746 out.writeInt(0);
5747 }
5748 }
5749 }
5750
5751 int NSE = u.mSensorStats.size();
5752 out.writeInt(NSE);
5753 if (NSE > 0) {
5754 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
5755 : u.mSensorStats.entrySet()) {
5756 out.writeInt(ent.getKey());
5757 Uid.Sensor se = ent.getValue();
5758 if (se.mTimer != null) {
5759 out.writeInt(1);
5760 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5761 } else {
5762 out.writeInt(0);
5763 }
5764 }
5765 }
5766
5767 int NP = u.mProcessStats.size();
5768 out.writeInt(NP);
5769 if (NP > 0) {
5770 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
5771 : u.mProcessStats.entrySet()) {
5772 out.writeString(ent.getKey());
5773 Uid.Proc ps = ent.getValue();
5774 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005775 out.writeLong(ps.mSystemTime);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005776 out.writeLong(ps.mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005777 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005778 final int N = ps.mSpeedBins.length;
5779 out.writeInt(N);
5780 for (int i=0; i<N; i++) {
5781 if (ps.mSpeedBins[i] != null) {
5782 out.writeInt(1);
5783 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
5784 } else {
5785 out.writeInt(0);
5786 }
5787 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005788 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005789 }
5790 }
5791
5792 NP = u.mPackageStats.size();
5793 out.writeInt(NP);
5794 if (NP > 0) {
5795 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
5796 : u.mPackageStats.entrySet()) {
5797 out.writeString(ent.getKey());
5798 Uid.Pkg ps = ent.getValue();
5799 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005800 final int NS = ps.mServiceStats.size();
5801 out.writeInt(NS);
5802 if (NS > 0) {
5803 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
5804 : ps.mServiceStats.entrySet()) {
5805 out.writeString(sent.getKey());
5806 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
5807 long time = ss.getStartTimeToNowLocked(NOW);
5808 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005809 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005810 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005811 }
5812 }
5813 }
5814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005815 }
5816 }
5817
5818 public void readFromParcel(Parcel in) {
5819 readFromParcelLocked(in);
5820 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005822 void readFromParcelLocked(Parcel in) {
5823 int magic = in.readInt();
5824 if (magic != MAGIC) {
5825 throw new ParcelFormatException("Bad magic number");
5826 }
5827
Dianne Hackbornae384452011-06-28 12:33:48 -07005828 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005830 mStartCount = in.readInt();
5831 mBatteryUptime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005832 mBatteryLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005833 mBatteryRealtime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005834 mBatteryLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005835 mScreenOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005836 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005837 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005838 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i,
5839 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005840 }
5841 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005842 mPhoneOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005843 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Wink Saville52840902011-02-18 12:40:47 -08005844 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005845 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
5846 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005847 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005848 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005849 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005850 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
5851 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005852 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005853 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5854 mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
5855 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005856 mWifiOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005857 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005858 mGlobalWifiRunning = false;
5859 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005860 mBluetoothOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005861 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005862 mUptime = in.readLong();
5863 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005864 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005865 mRealtime = in.readLong();
5866 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005867 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005868 mOnBattery = in.readInt() != 0;
5869 mOnBatteryInternal = false; // we are no longer really running.
5870 mTrackBatteryPastUptime = in.readLong();
5871 mTrackBatteryUptimeStart = in.readLong();
5872 mTrackBatteryPastRealtime = in.readLong();
5873 mTrackBatteryRealtimeStart = in.readLong();
5874 mUnpluggedBatteryUptime = in.readLong();
5875 mUnpluggedBatteryRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005876 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005877 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005878 mLowDischargeAmountSinceCharge = in.readInt();
5879 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005880 mDischargeAmountScreenOn = in.readInt();
5881 mDischargeAmountScreenOnSinceCharge = in.readInt();
5882 mDischargeAmountScreenOff = in.readInt();
5883 mDischargeAmountScreenOffSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005884 mLastWriteTime = in.readLong();
5885
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005886 mRadioDataUptime = in.readLong();
5887 mRadioDataStart = -1;
5888
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005889 mBluetoothPingCount = in.readInt();
5890 mBluetoothPingStart = -1;
5891
Evan Millarc64edde2009-04-18 12:26:32 -07005892 mKernelWakelockStats.clear();
5893 int NKW = in.readInt();
5894 for (int ikw = 0; ikw < NKW; ikw++) {
5895 if (in.readInt() != 0) {
5896 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005897 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07005898 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
5899 mKernelWakelockStats.put(wakelockName, kwlt);
5900 }
5901 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 mPartialTimers.clear();
5904 mFullTimers.clear();
5905 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005906 mWifiRunningTimers.clear();
5907 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -07005908 mWifiScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005909 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005910
Amith Yamasanie43530a2009-08-21 13:11:37 -07005911 sNumSpeedSteps = in.readInt();
5912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005913 int numUids = in.readInt();
5914 mUidStats.clear();
5915 for (int i = 0; i < numUids; i++) {
5916 int uid = in.readInt();
5917 Uid u = new Uid(uid);
5918 u.readFromParcelLocked(mUnpluggables, in);
5919 mUidStats.append(uid, u);
5920 }
5921 }
5922
5923 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005924 writeToParcelLocked(out, true, flags);
5925 }
5926
5927 public void writeToParcelWithoutUids(Parcel out, int flags) {
5928 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005929 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005930
5931 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005932 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005933 // Need to update with current kernel wake lock counts.
5934 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005935 updateNetworkActivityLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005937 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
5938 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
5939 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
5940 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005941
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005942 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005943
Dianne Hackbornae384452011-06-28 12:33:48 -07005944 writeHistory(out, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005946 out.writeInt(mStartCount);
5947 out.writeLong(mBatteryUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005948 out.writeLong(mBatteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005949 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005950 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5951 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
5952 }
5953 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005954 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Wink Saville52840902011-02-18 12:40:47 -08005955 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005956 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
5957 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005958 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005959 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5960 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
5961 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005962 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5963 mNetworkActivityCounters[i].writeToParcel(out);
5964 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005965 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005966 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005967 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005968 out.writeLong(mUptime);
5969 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005970 out.writeLong(mRealtime);
5971 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005972 out.writeInt(mOnBattery ? 1 : 0);
5973 out.writeLong(batteryUptime);
5974 out.writeLong(mTrackBatteryUptimeStart);
5975 out.writeLong(batteryRealtime);
5976 out.writeLong(mTrackBatteryRealtimeStart);
5977 out.writeLong(mUnpluggedBatteryUptime);
5978 out.writeLong(mUnpluggedBatteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005979 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005980 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005981 out.writeInt(mLowDischargeAmountSinceCharge);
5982 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005983 out.writeInt(mDischargeAmountScreenOn);
5984 out.writeInt(mDischargeAmountScreenOnSinceCharge);
5985 out.writeInt(mDischargeAmountScreenOff);
5986 out.writeInt(mDischargeAmountScreenOffSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005987 out.writeLong(mLastWriteTime);
5988
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005989 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07005990 out.writeLong(getRadioDataUptime());
5991
5992 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005993
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005994 if (inclUids) {
5995 out.writeInt(mKernelWakelockStats.size());
5996 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5997 SamplingTimer kwlt = ent.getValue();
5998 if (kwlt != null) {
5999 out.writeInt(1);
6000 out.writeString(ent.getKey());
6001 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
6002 } else {
6003 out.writeInt(0);
6004 }
Evan Millarc64edde2009-04-18 12:26:32 -07006005 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006006 } else {
6007 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07006008 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006009
6010 out.writeInt(sNumSpeedSteps);
6011
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006012 if (inclUids) {
6013 int size = mUidStats.size();
6014 out.writeInt(size);
6015 for (int i = 0; i < size; i++) {
6016 out.writeInt(mUidStats.keyAt(i));
6017 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006018
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006019 uid.writeToParcelLocked(out, batteryRealtime);
6020 }
6021 } else {
6022 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006023 }
6024 }
6025
6026 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
6027 new Parcelable.Creator<BatteryStatsImpl>() {
6028 public BatteryStatsImpl createFromParcel(Parcel in) {
6029 return new BatteryStatsImpl(in);
6030 }
6031
6032 public BatteryStatsImpl[] newArray(int size) {
6033 return new BatteryStatsImpl[size];
6034 }
6035 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006036
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006037 public void prepareForDumpLocked() {
6038 // Need to retrieve current kernel wake lock stats before printing.
6039 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006040 updateNetworkActivityLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006041 }
6042
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07006043 public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006044 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006045 Printer pr = new PrintWriterPrinter(pw);
6046 pr.println("*** Screen timer:");
6047 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07006048 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006049 pr.println("*** Screen brightness #" + i + ":");
6050 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07006051 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006052 pr.println("*** Input event counter:");
6053 mInputEventCounter.logState(pr, " ");
6054 pr.println("*** Phone timer:");
6055 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08006056 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006057 pr.println("*** Signal strength #" + i + ":");
6058 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07006059 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07006060 pr.println("*** Signal scanning :");
6061 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07006062 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006063 pr.println("*** Data connection type #" + i + ":");
6064 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07006065 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006066 pr.println("*** Wifi timer:");
6067 mWifiOnTimer.logState(pr, " ");
6068 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006069 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006070 pr.println("*** Bluetooth timer:");
6071 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006072 }
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07006073 super.dumpLocked(pw, isUnpluggedOnly, reqUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006074 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006075}